Introduction and Background

Agenda

Part I - Setting up the Data

  • Define the differences between Metabarcoding/Amplicon sequencing and Whole Shotgun Sequencing Metagenomics
  • Get some practice in RStudio OnDemand and using the Tufts Cluster
  • Learn about accessing interesting NCBI data through BioProjects and SRA Run Selector
  • Refine our quality control best practices to preprocess data we have generated or downloaded
  • Fastqc
  • Multiqc
  • Kmer-based filtering and trimming with BCBio tools

Part II - Practice a typical metagenomic workflow

  • Metagenome Assembly with Megahit
  • Assessing the Quality of an Assembly with Quast
  • Preliminary contamination screening with kraken
  • Visualization of kraken reports with the krona tool

The following items are not hands on, but will be shown as part of use case of a recent Metagenomics Workflow done in collaboration with a Tufts Researcher

  • Metagenome Binning and Refinement with MetaBat2, MaxBin and Concoct
  • Visualization of Sequence of Metagenomic Bins with BlobTools
  • Extracting Relevant Reads with BWA
  • Reassembly with Megahit from the Bins
  • Taxonomic Classification with Kaiju
  • Functional Classification with Prokka

If this sounds like a lot of ground to cover, you are correct!

In some portions of this tutorial, we don’t actually run the code, but jump ahead to the next step.

For these “skipped” portions, the code to run the process is provided.


Attach public library paths to your RStudio OnDemand session

The setup code adds the libraries in the order they will be searced for packages.

Setting .libpaths() to Tufts shared folders can reduce the amount of time spent downloading packages.

Please reach out to us about any difficult or tricky installs, sometimes it is a library package error that has to be fixed by an TTS HPC Research Technology Specialist.

Please make sure that the output to this code chunk has the shared library, “/cluster/tufts/hpc/tools/R/4.0.0” in position [1]

Example output (it depends what else you have been doing in RStudio before today).

[1] “/cluster/tufts/hpc/tools/R/4.0.0” [2] “/cluster/home/arhode05/R/x86_64-pc-linux-gnu-library/4.0” [3] “/opt/shared/R/4.0.0/lib64/R/library”

Commands to specify the shared directory as the first place to look for R libraries and check the output.

.libPaths(c('/cluster/tufts/hpc/tools/R/4.0.0',.libPaths()))

.libPaths()

This Metagenomics Tutorial is mainly a set of Bash Commands

This tutorial uses code chunks. To run an individual code chunk while the notebook is open in OnDemand RStudio, please press the green triangle on the upper right corner of the code chunk.

You may be wondering why we went through the trouble of having bash commands inside an R notebook for this tutorial. The simplest answer is that RStudio has the handy ability to open visualization files with a simple click on the file name in the lower right screen. This saves a lot of time and confusing navigation when doing this type of project, that produces a lot of intermediate files.

RStudio can run code chunks in other languages by resetting the code chunks to read that language.

  • {bash} indicates that the code chunk is in command line syntax, so these commands can be copied and pasted directly into a terminal

  • {r} indicates that the code chunk uses R-code

To save a bunch of copying/pasting, we are just going to run both types of these chunks inside our notebook using RStudio OnDemand.

The order of chunks is important, so if you skip one or get lost, it is possible to use the dropdown menu next to the word “Run” at the top of this window to run multiple chunks to get you back to where you started.

Any questions?


What other “kernels” are available in R notebook code chunks? (Hint - click the down arrow next to the "Insert Chunk command at the top of this window)

Modules and Conda Environments

In this workshop, we will sometimes be loading modules from the HPC to use in a code chunk.

Here is an example code chunk that loads a module for samtools and runs the command with the help flag to generate some output to test that the module loaded correctly.

If the bash environment is not designated in the setup chunk, you may need to add this bash command at the beginning of the chunk to enable module loading.

source ~/.bashrc


module load samtools/1.9
samtools --help

The behavior of modules in the code chunks differs from our direct command line.

The Rmarkdown notebook will not remember it from chunk to chunk. So load the modules in the chunks where the commands are needed.

An example with conda environments will be shown in Part II.


What happens when you run this chunk?

module list
No Modulefiles Currently Loaded.

Why use modules instead of conda environments?
  • Conda environments are great for installing specific versions of programs, but often bring in clashing dependencies, and only one is active at a time.

  • Using HPC modules can provide more integration because you can load several at one time.

  • Of course, conda environments could be used if you load all the required programs into the same environment. We will see an example of this later with Metawrap

Introducing the Data - Giant Panda ticks

Ticks are capable of spreading pathogens (viruses, bacteria and other parasites) among a host population. Not much is known about the spread of tick-borne viruses in Giant Pandas. The density of giant pandas in breeding captivity in Sichuan Province, China may lead to more transmission of these diseases. The researchers who loaded this data into the SRA were interested in characterizing the virome of these ticks and to compare these with the virome of the pandas.

We are not going to restrict our analysis to the virome, and just take a general look at what these ticks are carryng around in general using practical metagenomics workflows.

Check out the bioproject here

Check out the final paper here

Is he sleepy or is he sick?

We are going to bring in some of the data from this bioproject to our Metagenomics Tutorial space.

What information can we find in the metadata?

SRA Metadata - every project is different!

Example from BioProject Microbes From Mum

Mum sponge metadata

The Metadata from our BioProject

Panda tick metadata

Question - Why do most of the reads of “spot length” equal to 502?

Something you may have noticed is that the reads are suspicially even in number, at length 502. The experimental design states that the reads were paired-end 2x250.

Question - Who is responsible for loading BioProject metadata to the NCBI?

Obtaining Data from SRA

The data we are going to copy over can be obtained directly from the SRA by using our command line module for the SRAToolkit. This can take a little while, depending on the internet connection and which source the files are pulled from (on-prem, AWS or GCP).

“Spots” in SRA are not the same as “reads”

  • A spot is all the info you got from one “spot” on the flow cell.
  • You get 4 reads per spot with today’s illumina sequencing: forward barcode, forward read, reverse barcode, reverse read.

NCBI SRA “Spots”

Practice downloading data from SRA

We have a toolkit on the HPC cluster that allows users to pull data directly from SRA. The first step is configuring the SRA toolkit with a unique user ID. The second step is running either fastq-dump or fasterq-dump. We will use fastq-dump to demonstrate the options available.


module load /cluster/tufts/bio/tools/module_files/sra/3.0.0

#The next few lines set up your configuration for SRA and is necessary if you have not used the SRA toolkit previously.

#The vdb-config is an interactive tool, to generate a unique identifier. Since it is difficult to use it interactively from ROnDemand, this command opens the interactive screen for three seconds then closes it, which generates the user id.

vdb-config -i & read -t 3 ; kill $!
[?25l[?1000h[?1002h

module load /cluster/tufts/bio/tools/module_files/sra/3.0.0

mkdir -p test_SRA
fastq-dump --outdir test_SRA -X 500 --skip-technical --read-filter pass --readids --minReadLen 200 --split-e SRR18086364
Rejected 149 READS because READLEN < 200
Read 500 spots for SRR18086364
Written 426 spots for SRR18086364

Command Line Parameters

  • Grap first million lines -X 500
  • Only “biological reads” --skip-technical
  • Remove reads that are mostly N’s --read-filter pass
  • Append .1 to forward read header .2 to reverse read header –readids
  • Keep mated pairs and singletons, use -–split-e and a three files will be generated if orphans are present (forward, reverse, and unmatched mates)

There should be three new files in your Metagenomics2022/test_SRA directory.

The output is small enough that we can look into the fastq file by clicking on it.

  • Confirm the .1 and .2 were appended to your forward read headers and reverse read headers
  • What happened inside the singleton file? Do you see .1, .2 or both?
  • QC Best practice: Count the number of lines in the output files

wc -l ./test_SRA/*.fastq
  1700 ./test_SRA/SRR18086364_pass_1.fastq
  1700 ./test_SRA/SRR18086364_pass_2.fastq
     4 ./test_SRA/SRR18086364_pass.fastq
  3404 total
  • How many lines are in our fastq output files and why?

    (Hint 1: we asked for 500 “spots”, not reads) (Hint 2: how did our parameter choices affect our outputs?)

A Note about Fasterq-dump

In some cases, the newer version of this tool fasterq-dump will automatically run the split-e version of the command without adding this parameter. It is worth looking at the options before using it, because some of the parameter meanings have changed.

The following codeblock is for reference, to use the chunk, remove the # at the beginning of the line.


#/cluster/tufts/hpc/tools/spack/linux-rhel7-ivybridge/gcc-9.3.0/fastqc-0.11.9-eeij5jwnwau3ttx4m53bxafmxbhm4fjz/bin/fastqc ./MGData/*overrep.fastq

#source ~/.bashrc
module load fastqc
mkdir -p fastqc
fastqc ./data/*pass*.fastq -o fastqc
Started analysis of SRR18085691_pass_1.fastq
Approx 5% complete for SRR18085691_pass_1.fastq
Approx 10% complete for SRR18085691_pass_1.fastq
Approx 15% complete for SRR18085691_pass_1.fastq
Approx 20% complete for SRR18085691_pass_1.fastq
Approx 25% complete for SRR18085691_pass_1.fastq
Approx 30% complete for SRR18085691_pass_1.fastq
Approx 35% complete for SRR18085691_pass_1.fastq
Approx 40% complete for SRR18085691_pass_1.fastq
Approx 45% complete for SRR18085691_pass_1.fastq
Approx 50% complete for SRR18085691_pass_1.fastq
Approx 55% complete for SRR18085691_pass_1.fastq
Approx 60% complete for SRR18085691_pass_1.fastq
Approx 65% complete for SRR18085691_pass_1.fastq
Approx 70% complete for SRR18085691_pass_1.fastq
Approx 75% complete for SRR18085691_pass_1.fastq
Approx 80% complete for SRR18085691_pass_1.fastq
Approx 85% complete for SRR18085691_pass_1.fastq
Approx 90% complete for SRR18085691_pass_1.fastq
Approx 95% complete for SRR18085691_pass_1.fastq
Analysis complete for SRR18085691_pass_1.fastq
Approx 100% complete for SRR18085691_pass_1.fastq
Started analysis of SRR18085691_pass_2.fastq
Approx 5% complete for SRR18085691_pass_2.fastq
Approx 10% complete for SRR18085691_pass_2.fastq
Approx 15% complete for SRR18085691_pass_2.fastq
Approx 20% complete for SRR18085691_pass_2.fastq
Approx 25% complete for SRR18085691_pass_2.fastq
Approx 30% complete for SRR18085691_pass_2.fastq
Approx 35% complete for SRR18085691_pass_2.fastq
Approx 40% complete for SRR18085691_pass_2.fastq
Approx 45% complete for SRR18085691_pass_2.fastq
Approx 50% complete for SRR18085691_pass_2.fastq
Approx 55% complete for SRR18085691_pass_2.fastq
Approx 60% complete for SRR18085691_pass_2.fastq
Approx 65% complete for SRR18085691_pass_2.fastq
Approx 70% complete for SRR18085691_pass_2.fastq
Approx 75% complete for SRR18085691_pass_2.fastq
Approx 80% complete for SRR18085691_pass_2.fastq
Approx 85% complete for SRR18085691_pass_2.fastq
Approx 90% complete for SRR18085691_pass_2.fastq
Approx 95% complete for SRR18085691_pass_2.fastq
Analysis complete for SRR18085691_pass_2.fastq
Approx 100% complete for SRR18085691_pass_2.fastq
Started analysis of SRR18085708_pass_1.fastq
Approx 5% complete for SRR18085708_pass_1.fastq
Approx 10% complete for SRR18085708_pass_1.fastq
Approx 15% complete for SRR18085708_pass_1.fastq
Approx 20% complete for SRR18085708_pass_1.fastq
Approx 25% complete for SRR18085708_pass_1.fastq
Approx 30% complete for SRR18085708_pass_1.fastq
Approx 35% complete for SRR18085708_pass_1.fastq
Approx 40% complete for SRR18085708_pass_1.fastq
Approx 45% complete for SRR18085708_pass_1.fastq
Approx 50% complete for SRR18085708_pass_1.fastq
Approx 55% complete for SRR18085708_pass_1.fastq
Approx 60% complete for SRR18085708_pass_1.fastq
Approx 65% complete for SRR18085708_pass_1.fastq
Approx 70% complete for SRR18085708_pass_1.fastq
Approx 75% complete for SRR18085708_pass_1.fastq
Approx 80% complete for SRR18085708_pass_1.fastq
Approx 85% complete for SRR18085708_pass_1.fastq
Approx 90% complete for SRR18085708_pass_1.fastq
Approx 95% complete for SRR18085708_pass_1.fastq
Analysis complete for SRR18085708_pass_1.fastq
Approx 100% complete for SRR18085708_pass_1.fastq
Started analysis of SRR18085708_pass_2.fastq
Approx 5% complete for SRR18085708_pass_2.fastq
Approx 10% complete for SRR18085708_pass_2.fastq
Approx 15% complete for SRR18085708_pass_2.fastq
Approx 20% complete for SRR18085708_pass_2.fastq
Approx 25% complete for SRR18085708_pass_2.fastq
Approx 30% complete for SRR18085708_pass_2.fastq
Approx 35% complete for SRR18085708_pass_2.fastq
Approx 40% complete for SRR18085708_pass_2.fastq
Approx 45% complete for SRR18085708_pass_2.fastq
Approx 50% complete for SRR18085708_pass_2.fastq
Approx 55% complete for SRR18085708_pass_2.fastq
Approx 60% complete for SRR18085708_pass_2.fastq
Approx 65% complete for SRR18085708_pass_2.fastq
Approx 70% complete for SRR18085708_pass_2.fastq
Approx 75% complete for SRR18085708_pass_2.fastq
Approx 80% complete for SRR18085708_pass_2.fastq
Approx 85% complete for SRR18085708_pass_2.fastq
Approx 90% complete for SRR18085708_pass_2.fastq
Approx 95% complete for SRR18085708_pass_2.fastq
Analysis complete for SRR18085708_pass_2.fastq
Approx 100% complete for SRR18085708_pass_2.fastq
Started analysis of SRR18086277_pass_1.fastq
Approx 5% complete for SRR18086277_pass_1.fastq
Approx 10% complete for SRR18086277_pass_1.fastq
Approx 15% complete for SRR18086277_pass_1.fastq
Approx 20% complete for SRR18086277_pass_1.fastq
Approx 25% complete for SRR18086277_pass_1.fastq
Approx 30% complete for SRR18086277_pass_1.fastq
Approx 35% complete for SRR18086277_pass_1.fastq
Approx 40% complete for SRR18086277_pass_1.fastq
Approx 45% complete for SRR18086277_pass_1.fastq
Approx 50% complete for SRR18086277_pass_1.fastq
Approx 55% complete for SRR18086277_pass_1.fastq
Approx 60% complete for SRR18086277_pass_1.fastq
Approx 65% complete for SRR18086277_pass_1.fastq
Approx 70% complete for SRR18086277_pass_1.fastq
Approx 75% complete for SRR18086277_pass_1.fastq
Approx 80% complete for SRR18086277_pass_1.fastq
Approx 85% complete for SRR18086277_pass_1.fastq
Approx 90% complete for SRR18086277_pass_1.fastq
Approx 95% complete for SRR18086277_pass_1.fastq
Analysis complete for SRR18086277_pass_1.fastq
Approx 100% complete for SRR18086277_pass_1.fastq
Started analysis of SRR18086277_pass_2.fastq
Approx 5% complete for SRR18086277_pass_2.fastq
Approx 10% complete for SRR18086277_pass_2.fastq
Approx 15% complete for SRR18086277_pass_2.fastq
Approx 20% complete for SRR18086277_pass_2.fastq
Approx 25% complete for SRR18086277_pass_2.fastq
Approx 30% complete for SRR18086277_pass_2.fastq
Approx 35% complete for SRR18086277_pass_2.fastq
Approx 40% complete for SRR18086277_pass_2.fastq
Approx 45% complete for SRR18086277_pass_2.fastq
Approx 50% complete for SRR18086277_pass_2.fastq
Approx 55% complete for SRR18086277_pass_2.fastq
Approx 60% complete for SRR18086277_pass_2.fastq
Approx 65% complete for SRR18086277_pass_2.fastq
Approx 70% complete for SRR18086277_pass_2.fastq
Approx 75% complete for SRR18086277_pass_2.fastq
Approx 80% complete for SRR18086277_pass_2.fastq
Approx 85% complete for SRR18086277_pass_2.fastq
Approx 90% complete for SRR18086277_pass_2.fastq
Approx 95% complete for SRR18086277_pass_2.fastq
Analysis complete for SRR18086277_pass_2.fastq
Approx 100% complete for SRR18086277_pass_2.fastq
Started analysis of SRR18086342_pass_1.fastq
Approx 5% complete for SRR18086342_pass_1.fastq
Approx 10% complete for SRR18086342_pass_1.fastq
Approx 15% complete for SRR18086342_pass_1.fastq
Approx 20% complete for SRR18086342_pass_1.fastq
Approx 25% complete for SRR18086342_pass_1.fastq
Approx 30% complete for SRR18086342_pass_1.fastq
Approx 35% complete for SRR18086342_pass_1.fastq
Approx 40% complete for SRR18086342_pass_1.fastq
Approx 45% complete for SRR18086342_pass_1.fastq
Approx 50% complete for SRR18086342_pass_1.fastq
Approx 55% complete for SRR18086342_pass_1.fastq
Approx 60% complete for SRR18086342_pass_1.fastq
Approx 65% complete for SRR18086342_pass_1.fastq
Approx 70% complete for SRR18086342_pass_1.fastq
Approx 75% complete for SRR18086342_pass_1.fastq
Approx 80% complete for SRR18086342_pass_1.fastq
Approx 85% complete for SRR18086342_pass_1.fastq
Approx 90% complete for SRR18086342_pass_1.fastq
Approx 95% complete for SRR18086342_pass_1.fastq
Analysis complete for SRR18086342_pass_1.fastq
Started analysis of SRR18086342_pass_2.fastq
Approx 5% complete for SRR18086342_pass_2.fastq
Approx 10% complete for SRR18086342_pass_2.fastq
Approx 15% complete for SRR18086342_pass_2.fastq
Approx 20% complete for SRR18086342_pass_2.fastq
Approx 25% complete for SRR18086342_pass_2.fastq
Approx 30% complete for SRR18086342_pass_2.fastq
Approx 35% complete for SRR18086342_pass_2.fastq
Approx 40% complete for SRR18086342_pass_2.fastq
Approx 45% complete for SRR18086342_pass_2.fastq
Approx 50% complete for SRR18086342_pass_2.fastq
Approx 55% complete for SRR18086342_pass_2.fastq
Approx 60% complete for SRR18086342_pass_2.fastq
Approx 65% complete for SRR18086342_pass_2.fastq
Approx 70% complete for SRR18086342_pass_2.fastq
Approx 75% complete for SRR18086342_pass_2.fastq
Approx 80% complete for SRR18086342_pass_2.fastq
Approx 85% complete for SRR18086342_pass_2.fastq
Approx 90% complete for SRR18086342_pass_2.fastq
Approx 95% complete for SRR18086342_pass_2.fastq
Analysis complete for SRR18086342_pass_2.fastq
Started analysis of SRR18086364_pass_1.fastq
Approx 5% complete for SRR18086364_pass_1.fastq
Approx 10% complete for SRR18086364_pass_1.fastq
Approx 15% complete for SRR18086364_pass_1.fastq
Approx 20% complete for SRR18086364_pass_1.fastq
Approx 25% complete for SRR18086364_pass_1.fastq
Approx 30% complete for SRR18086364_pass_1.fastq
Approx 35% complete for SRR18086364_pass_1.fastq
Approx 40% complete for SRR18086364_pass_1.fastq
Approx 45% complete for SRR18086364_pass_1.fastq
Approx 50% complete for SRR18086364_pass_1.fastq
Approx 55% complete for SRR18086364_pass_1.fastq
Approx 60% complete for SRR18086364_pass_1.fastq
Approx 65% complete for SRR18086364_pass_1.fastq
Approx 70% complete for SRR18086364_pass_1.fastq
Approx 75% complete for SRR18086364_pass_1.fastq
Approx 80% complete for SRR18086364_pass_1.fastq
Approx 85% complete for SRR18086364_pass_1.fastq
Approx 90% complete for SRR18086364_pass_1.fastq
Analysis complete for SRR18086364_pass_1.fastq
Approx 95% complete for SRR18086364_pass_1.fastq
Started analysis of SRR18086364_pass_2.fastq
Approx 5% complete for SRR18086364_pass_2.fastq
Approx 10% complete for SRR18086364_pass_2.fastq
Approx 15% complete for SRR18086364_pass_2.fastq
Approx 20% complete for SRR18086364_pass_2.fastq
Approx 25% complete for SRR18086364_pass_2.fastq
Approx 30% complete for SRR18086364_pass_2.fastq
Approx 35% complete for SRR18086364_pass_2.fastq
Approx 40% complete for SRR18086364_pass_2.fastq
Approx 45% complete for SRR18086364_pass_2.fastq
Approx 50% complete for SRR18086364_pass_2.fastq
Approx 55% complete for SRR18086364_pass_2.fastq
Approx 60% complete for SRR18086364_pass_2.fastq
Approx 65% complete for SRR18086364_pass_2.fastq
Approx 70% complete for SRR18086364_pass_2.fastq
Approx 75% complete for SRR18086364_pass_2.fastq
Approx 80% complete for SRR18086364_pass_2.fastq
Approx 85% complete for SRR18086364_pass_2.fastq
Approx 90% complete for SRR18086364_pass_2.fastq
Analysis complete for SRR18086364_pass_2.fastq
Approx 95% complete for SRR18086364_pass_2.fastq
Analysis complete for SRR18086364_pass.fastq
Started analysis of SRR18086364_pass.fastq
Started analysis of SRR18086575_pass_1.fastq
Approx 5% complete for SRR18086575_pass_1.fastq
Approx 10% complete for SRR18086575_pass_1.fastq
Approx 15% complete for SRR18086575_pass_1.fastq
Approx 20% complete for SRR18086575_pass_1.fastq
Approx 25% complete for SRR18086575_pass_1.fastq
Approx 30% complete for SRR18086575_pass_1.fastq
Approx 35% complete for SRR18086575_pass_1.fastq
Approx 40% complete for SRR18086575_pass_1.fastq
Approx 45% complete for SRR18086575_pass_1.fastq
Approx 50% complete for SRR18086575_pass_1.fastq
Approx 55% complete for SRR18086575_pass_1.fastq
Approx 60% complete for SRR18086575_pass_1.fastq
Approx 65% complete for SRR18086575_pass_1.fastq
Approx 70% complete for SRR18086575_pass_1.fastq
Approx 75% complete for SRR18086575_pass_1.fastq
Approx 80% complete for SRR18086575_pass_1.fastq
Approx 85% complete for SRR18086575_pass_1.fastq
Approx 90% complete for SRR18086575_pass_1.fastq
Approx 95% complete for SRR18086575_pass_1.fastq
Analysis complete for SRR18086575_pass_1.fastq
Approx 100% complete for SRR18086575_pass_1.fastq
Started analysis of SRR18086575_pass_2.fastq
Approx 5% complete for SRR18086575_pass_2.fastq
Approx 10% complete for SRR18086575_pass_2.fastq
Approx 15% complete for SRR18086575_pass_2.fastq
Approx 20% complete for SRR18086575_pass_2.fastq
Approx 25% complete for SRR18086575_pass_2.fastq
Approx 30% complete for SRR18086575_pass_2.fastq
Approx 35% complete for SRR18086575_pass_2.fastq
Approx 40% complete for SRR18086575_pass_2.fastq
Approx 45% complete for SRR18086575_pass_2.fastq
Approx 50% complete for SRR18086575_pass_2.fastq
Approx 55% complete for SRR18086575_pass_2.fastq
Approx 60% complete for SRR18086575_pass_2.fastq
Approx 65% complete for SRR18086575_pass_2.fastq
Approx 70% complete for SRR18086575_pass_2.fastq
Approx 75% complete for SRR18086575_pass_2.fastq
Approx 80% complete for SRR18086575_pass_2.fastq
Approx 85% complete for SRR18086575_pass_2.fastq
Approx 90% complete for SRR18086575_pass_2.fastq
Approx 95% complete for SRR18086575_pass_2.fastq
Analysis complete for SRR18086575_pass_2.fastq
Approx 100% complete for SRR18086575_pass_2.fastq
Started analysis of SRR18091316_pass_1.fastq
Approx 5% complete for SRR18091316_pass_1.fastq
Approx 10% complete for SRR18091316_pass_1.fastq
Approx 15% complete for SRR18091316_pass_1.fastq
Approx 20% complete for SRR18091316_pass_1.fastq
Approx 25% complete for SRR18091316_pass_1.fastq
Approx 30% complete for SRR18091316_pass_1.fastq
Approx 35% complete for SRR18091316_pass_1.fastq
Approx 40% complete for SRR18091316_pass_1.fastq
Approx 45% complete for SRR18091316_pass_1.fastq
Approx 50% complete for SRR18091316_pass_1.fastq
Approx 55% complete for SRR18091316_pass_1.fastq
Approx 60% complete for SRR18091316_pass_1.fastq
Approx 65% complete for SRR18091316_pass_1.fastq
Approx 70% complete for SRR18091316_pass_1.fastq
Approx 75% complete for SRR18091316_pass_1.fastq
Approx 80% complete for SRR18091316_pass_1.fastq
Approx 85% complete for SRR18091316_pass_1.fastq
Approx 90% complete for SRR18091316_pass_1.fastq
Approx 95% complete for SRR18091316_pass_1.fastq
Analysis complete for SRR18091316_pass_1.fastq
Approx 100% complete for SRR18091316_pass_1.fastq
Started analysis of SRR18091316_pass_2.fastq
Approx 5% complete for SRR18091316_pass_2.fastq
Approx 10% complete for SRR18091316_pass_2.fastq
Approx 15% complete for SRR18091316_pass_2.fastq
Approx 20% complete for SRR18091316_pass_2.fastq
Approx 25% complete for SRR18091316_pass_2.fastq
Approx 30% complete for SRR18091316_pass_2.fastq
Approx 35% complete for SRR18091316_pass_2.fastq
Approx 40% complete for SRR18091316_pass_2.fastq
Approx 45% complete for SRR18091316_pass_2.fastq
Approx 50% complete for SRR18091316_pass_2.fastq
Approx 55% complete for SRR18091316_pass_2.fastq
Approx 60% complete for SRR18091316_pass_2.fastq
Approx 65% complete for SRR18091316_pass_2.fastq
Approx 70% complete for SRR18091316_pass_2.fastq
Approx 75% complete for SRR18091316_pass_2.fastq
Approx 80% complete for SRR18091316_pass_2.fastq
Approx 85% complete for SRR18091316_pass_2.fastq
Approx 90% complete for SRR18091316_pass_2.fastq
Approx 95% complete for SRR18091316_pass_2.fastq
Analysis complete for SRR18091316_pass_2.fastq
Approx 100% complete for SRR18091316_pass_2.fastq
Started analysis of SRR18091737_pass_1.fastq
Approx 5% complete for SRR18091737_pass_1.fastq
Approx 10% complete for SRR18091737_pass_1.fastq
Approx 15% complete for SRR18091737_pass_1.fastq
Approx 20% complete for SRR18091737_pass_1.fastq
Approx 25% complete for SRR18091737_pass_1.fastq
Approx 30% complete for SRR18091737_pass_1.fastq
Approx 35% complete for SRR18091737_pass_1.fastq
Approx 40% complete for SRR18091737_pass_1.fastq
Approx 45% complete for SRR18091737_pass_1.fastq
Approx 50% complete for SRR18091737_pass_1.fastq
Approx 55% complete for SRR18091737_pass_1.fastq
Approx 60% complete for SRR18091737_pass_1.fastq
Approx 65% complete for SRR18091737_pass_1.fastq
Approx 70% complete for SRR18091737_pass_1.fastq
Approx 75% complete for SRR18091737_pass_1.fastq
Approx 80% complete for SRR18091737_pass_1.fastq
Approx 85% complete for SRR18091737_pass_1.fastq
Approx 90% complete for SRR18091737_pass_1.fastq
Approx 95% complete for SRR18091737_pass_1.fastq
Analysis complete for SRR18091737_pass_1.fastq
Approx 100% complete for SRR18091737_pass_1.fastq
Started analysis of SRR18091737_pass_2.fastq
Approx 5% complete for SRR18091737_pass_2.fastq
Approx 10% complete for SRR18091737_pass_2.fastq
Approx 15% complete for SRR18091737_pass_2.fastq
Approx 20% complete for SRR18091737_pass_2.fastq
Approx 25% complete for SRR18091737_pass_2.fastq
Approx 30% complete for SRR18091737_pass_2.fastq
Approx 35% complete for SRR18091737_pass_2.fastq
Approx 40% complete for SRR18091737_pass_2.fastq
Approx 45% complete for SRR18091737_pass_2.fastq
Approx 50% complete for SRR18091737_pass_2.fastq
Approx 55% complete for SRR18091737_pass_2.fastq
Approx 60% complete for SRR18091737_pass_2.fastq
Approx 65% complete for SRR18091737_pass_2.fastq
Approx 70% complete for SRR18091737_pass_2.fastq
Approx 75% complete for SRR18091737_pass_2.fastq
Approx 80% complete for SRR18091737_pass_2.fastq
Approx 85% complete for SRR18091737_pass_2.fastq
Approx 90% complete for SRR18091737_pass_2.fastq
Approx 95% complete for SRR18091737_pass_2.fastq
Analysis complete for SRR18091737_pass_2.fastq
Approx 100% complete for SRR18091737_pass_2.fastq

#source ~/.bashrc
module load multiqc/1.7.0
mkdir -p multiqc
multiqc ./fastqc -o ./multiqc
[WARNING]         multiqc : MultiQC Version v1.13 now available!
[INFO   ]         multiqc : This is MultiQC v1.7
[INFO   ]         multiqc : Template    : default
[INFO   ]         multiqc : Searching './fastqc'
[INFO   ]          fastqc : Found 17 reports
[INFO   ]         multiqc : Compressing plot data
[INFO   ]         multiqc : Report      : multiqc/multiqc_report.html
[INFO   ]         multiqc : Data        : multiqc/multiqc_data
[INFO   ]         multiqc : MultiQC complete

Check the quality of your results by navigating to the file folder for multiqc and clicking on the html files that were generated.

Okay, so the data is not the most perfect, but we just need a set that can make it through the analysis.

Preprocessing Reads

Metagenomics has benefited from k-mer based approaches.

BCBio tools are useful for cleaining metagenomics files, because many simple functions can be called and sped up using kmers.

For example, let’s remove known adapter and other contamination using the NCBI database called “UniVec”


cd ~/Metagenomics2022
#pwd

#grep "TruSeq" ./contaminants/UniVec.fasta

grep "PCR Primer Index 9" ./contaminants/UniVec.fasta
>gnl|uv|NGB00802.1:1-63 Illumina TruSeq Small RNA Sample Prep Kit RNA PCR Primer Index 9 (RPI9) (Oligonucleotide sequence copyright 2007-2012 Illumina, Inc. All rights reserved.)
>gnl|uv|NGB00372.1:1-43 Illumina Multiplexing PCR Primer Index 9 (Oligonucleotide sequence copyright 2007-2012 Illumina, Inc. All rights reserved.)

Remove contamination from sequences with BCBio tools

Are these repeats biological (part of the genome) or technical (primer amplification, underabundance of sample or lack of PhiX spike-in)? What does the raw sequencing data show us?

Here is an example of how bbduk.sh can be used to simultaneously remove adapters, phiX spike-in and overrepresented sequences from our custom file.


#source ~/.bashrc
module load java/1.8.0_60
module load /cluster/tufts/bio/tools/module_files/bcbio/1.1.5
mkdir -p decon


bbduk.sh -Xmx10g -tbo  -tpe \
in1=data/SRR18085691_pass_1.fastq \
in2=data/SRR18085691_pass_2.fastq \
out1=decon/SRR18085691_decon_1.fastq \
out2=decon/SRR18085691_decon_2.fastq \
outs=decon/SRR18085691_decon_sing.fastq \
ref=contaminants/UniVec.fasta \
ref=contaminants/overrep.fasta \
ref=phix \
ktrim=r k=21 rcomp=t mink=11 hdist=2 minlen=200 \
java -Djava.library.path=/cluster/tufts/bio/tools/bcbio/1.1.5/anaconda/opt/bbmap-38.46-0/jni/ -ea -Xmx10g -Xms10g -cp /cluster/tufts/bio/tools/bcbio/1.1.5/anaconda/opt/bbmap-38.46-0/current/ jgi.BBDuk -Xmx10g -tbo -tpe in1=data/SRR18085691_pass_1.fastq in2=data/SRR18085691_pass_2.fastq out1=decon/SRR18085691_decon_1.fastq out2=decon/SRR18085691_decon_2.fastq outs=decon/SRR18085691_decon_sing.fastq ref=contaminants/UniVec.fasta ref=contaminants/overrep.fasta ref=phix ktrim=r k=21 rcomp=t mink=11 hdist=2 minlen=200
Executing jgi.BBDuk [-Xmx10g, tbo, tpe, in1=data/SRR18085691_pass_1.fastq, in2=data/SRR18085691_pass_2.fastq, out1=decon/SRR18085691_decon_1.fastq, out2=decon/SRR18085691_decon_2.fastq, outs=decon/SRR18085691_decon_sing.fastq, ref=contaminants/UniVec.fasta, ref=contaminants/overrep.fasta, ref=phix, ktrim=r, k=21, rcomp=t, mink=11, hdist=2, minlen=200]
Version 38.46

maskMiddle was disabled because useShortKmers=true
0.036 seconds.
Initial:
Memory: max=10290m, total=10290m, free=9968m, used=322m

Added 10506850 kmers; time:     5.863 seconds.
Memory: max=10290m, total=10290m, free=9233m, used=1057m

Input is being processed as paired
Started output streams: 0.066 seconds.
Processing time:        81.613 seconds.

Input:                      2000000 reads       502000000 bases.
KTrimmed:                   10970 reads (0.55%)     1959602 bases (0.39%)
Trimmed by overlap:         112718 reads (5.64%)    6611950 bases (1.32%)
Total Removed:              57438 reads (2.87%)     15942726 bases (3.18%)
Result:                     1942562 reads (97.13%)  486057274 bases (96.82%)

Time:                           87.544 seconds.
Reads Processed:       2000k    22.85k reads/sec
Bases Processed:        502m    5.73m bases/sec

While the next chunk is running, let’s talk about kmer-based approaches to filtering.

BBDUK = Decontamination Using Kmers

  • -tbo trims overlapping bases in paired end reads
  • -tpe trims both paired end reads to the same length
  • -in1,-in2,out1,out2,outs means input forward and reverse reads and output forward and reverse plus orphaned reads
  • ref can be any file in fasta format or baked-in options such as phiX and adapters
  • ref can be replaced with literal=ACTGGT,TTTGGTG with any list of strings
  • ktrim=r means to trim from 3-prime end
  • k refers to the kmer size that is chosen
  • mink allows a shorter kmer size at the end of the sequence
  • hdist refers to hamming distance - number of mismatches allowed in a kmer
  • minlen indicates the minimum length of the sequence to keep after trimming

#source ~/.bashrc
module load java/1.8.0_60
module load /cluster/tufts/bio/tools/module_files/bcbio/1.1.5
mkdir -p decon


ls data/*_pass_1.fastq | while read line ; do \

bbduk.sh -Xmx10g -tbo -tpe \
in1=$line \
in2=data/$(basename $line _pass_1.fastq)_pass_2.fastq \
out1=decon/$(basename $line _pass_1.fastq)_decon_1.fastq \
out2=decon/$(basename $line _pass_1.fastq)_decon_2.fastq\ \
outs=decon/$(basename $line _pass_1.fastq)_decon_sing.fastq \
ref=contaminants/UniVec.fasta \
ref=contaminants/overrep.fasta \
ref=phix \
ktrim=r k=21 rcomp=t mink=11 hdist=2 minlen=200; \
done
java -Djava.library.path=/cluster/tufts/bio/tools/bcbio/1.1.5/anaconda/opt/bbmap-38.46-0/jni/ -ea -Xmx10g -Xms10g -cp /cluster/tufts/bio/tools/bcbio/1.1.5/anaconda/opt/bbmap-38.46-0/current/ jgi.BBDuk -Xmx10g -tbo -tpe in1=data/SRR18085691_pass_1.fastq in2=data/SRR18085691_pass_2.fastq out1=decon/SRR18085691_decon_1.fastq out2=decon/SRR18085691_decon_2.fastq outs=decon/SRR18085691_decon_sing.fastq ref=contaminants/UniVec.fasta ref=contaminants/overrep.fasta ref=phix ktrim=r k=21 rcomp=t mink=11 hdist=2 minlen=200
Executing jgi.BBDuk [-Xmx10g, tbo, tpe, in1=data/SRR18085691_pass_1.fastq, in2=data/SRR18085691_pass_2.fastq, out1=decon/SRR18085691_decon_1.fastq, out2=decon/SRR18085691_decon_2.fastq, outs=decon/SRR18085691_decon_sing.fastq, ref=contaminants/UniVec.fasta, ref=contaminants/overrep.fasta, ref=phix, ktrim=r, k=21, rcomp=t, mink=11, hdist=2, minlen=200]
Version 38.46

maskMiddle was disabled because useShortKmers=true
0.037 seconds.
Initial:
Memory: max=10290m, total=10290m, free=9859m, used=431m

Added 10506850 kmers; time:     5.765 seconds.
Memory: max=10290m, total=10290m, free=9124m, used=1166m

Input is being processed as paired
Started output streams: 0.374 seconds.
Processing time:        83.866 seconds.

Input:                      2000000 reads       502000000 bases.
KTrimmed:                   10970 reads (0.55%)     1959602 bases (0.39%)
Trimmed by overlap:         112718 reads (5.64%)    6611950 bases (1.32%)
Total Removed:              57438 reads (2.87%)     15942726 bases (3.18%)
Result:                     1942562 reads (97.13%)  486057274 bases (96.82%)

Time:                           90.007 seconds.
Reads Processed:       2000k    22.22k reads/sec
Bases Processed:        502m    5.58m bases/sec
java -Djava.library.path=/cluster/tufts/bio/tools/bcbio/1.1.5/anaconda/opt/bbmap-38.46-0/jni/ -ea -Xmx10g -Xms10g -cp /cluster/tufts/bio/tools/bcbio/1.1.5/anaconda/opt/bbmap-38.46-0/current/ jgi.BBDuk -Xmx10g -tbo -tpe in1=data/SRR18085708_pass_1.fastq in2=data/SRR18085708_pass_2.fastq out1=decon/SRR18085708_decon_1.fastq out2=decon/SRR18085708_decon_2.fastq outs=decon/SRR18085708_decon_sing.fastq ref=contaminants/UniVec.fasta ref=contaminants/overrep.fasta ref=phix ktrim=r k=21 rcomp=t mink=11 hdist=2 minlen=200
Executing jgi.BBDuk [-Xmx10g, tbo, tpe, in1=data/SRR18085708_pass_1.fastq, in2=data/SRR18085708_pass_2.fastq, out1=decon/SRR18085708_decon_1.fastq, out2=decon/SRR18085708_decon_2.fastq, outs=decon/SRR18085708_decon_sing.fastq, ref=contaminants/UniVec.fasta, ref=contaminants/overrep.fasta, ref=phix, ktrim=r, k=21, rcomp=t, mink=11, hdist=2, minlen=200]
Version 38.46

maskMiddle was disabled because useShortKmers=true
0.030 seconds.
Initial:
Memory: max=10290m, total=10290m, free=9914m, used=376m

Added 10506850 kmers; time:     6.912 seconds.
Memory: max=10290m, total=10290m, free=9179m, used=1111m

Input is being processed as paired
Started output streams: 0.058 seconds.
Processing time:        70.165 seconds.

Input:                      2000000 reads       502000000 bases.
KTrimmed:                   2840 reads (0.14%)  360174 bases (0.07%)
Trimmed by overlap:         195124 reads (9.76%)    25710564 bases (5.12%)
Total Removed:              161564 reads (8.08%)    41435452 bases (8.25%)
Result:                     1838436 reads (91.92%)  460564548 bases (91.75%)

Time:                           77.137 seconds.
Reads Processed:       2000k    25.93k reads/sec
Bases Processed:        502m    6.51m bases/sec
java -Djava.library.path=/cluster/tufts/bio/tools/bcbio/1.1.5/anaconda/opt/bbmap-38.46-0/jni/ -ea -Xmx10g -Xms10g -cp /cluster/tufts/bio/tools/bcbio/1.1.5/anaconda/opt/bbmap-38.46-0/current/ jgi.BBDuk -Xmx10g -tbo -tpe in1=data/SRR18086277_pass_1.fastq in2=data/SRR18086277_pass_2.fastq out1=decon/SRR18086277_decon_1.fastq out2=decon/SRR18086277_decon_2.fastq outs=decon/SRR18086277_decon_sing.fastq ref=contaminants/UniVec.fasta ref=contaminants/overrep.fasta ref=phix ktrim=r k=21 rcomp=t mink=11 hdist=2 minlen=200
Executing jgi.BBDuk [-Xmx10g, tbo, tpe, in1=data/SRR18086277_pass_1.fastq, in2=data/SRR18086277_pass_2.fastq, out1=decon/SRR18086277_decon_1.fastq, out2=decon/SRR18086277_decon_2.fastq, outs=decon/SRR18086277_decon_sing.fastq, ref=contaminants/UniVec.fasta, ref=contaminants/overrep.fasta, ref=phix, ktrim=r, k=21, rcomp=t, mink=11, hdist=2, minlen=200]
Version 38.46

maskMiddle was disabled because useShortKmers=true
0.039 seconds.
Initial:
Memory: max=10290m, total=10290m, free=9860m, used=430m

Added 10506850 kmers; time:     6.574 seconds.
Memory: max=10290m, total=10290m, free=9126m, used=1164m

Input is being processed as paired
Started output streams: 0.040 seconds.
Processing time:        79.791 seconds.

Input:                      2000000 reads       502000000 bases.
KTrimmed:                   918 reads (0.05%)   198378 bases (0.04%)
Trimmed by overlap:         141132 reads (7.06%)    22658800 bases (4.51%)
Total Removed:              134148 reads (6.71%)    33887548 bases (6.75%)
Result:                     1865852 reads (93.29%)  468112452 bases (93.25%)

Time:                           86.407 seconds.
Reads Processed:       2000k    23.15k reads/sec
Bases Processed:        502m    5.81m bases/sec
java -Djava.library.path=/cluster/tufts/bio/tools/bcbio/1.1.5/anaconda/opt/bbmap-38.46-0/jni/ -ea -Xmx10g -Xms10g -cp /cluster/tufts/bio/tools/bcbio/1.1.5/anaconda/opt/bbmap-38.46-0/current/ jgi.BBDuk -Xmx10g -tbo -tpe in1=data/SRR18086342_pass_1.fastq in2=data/SRR18086342_pass_2.fastq out1=decon/SRR18086342_decon_1.fastq out2=decon/SRR18086342_decon_2.fastq outs=decon/SRR18086342_decon_sing.fastq ref=contaminants/UniVec.fasta ref=contaminants/overrep.fasta ref=phix ktrim=r k=21 rcomp=t mink=11 hdist=2 minlen=200
Executing jgi.BBDuk [-Xmx10g, tbo, tpe, in1=data/SRR18086342_pass_1.fastq, in2=data/SRR18086342_pass_2.fastq, out1=decon/SRR18086342_decon_1.fastq, out2=decon/SRR18086342_decon_2.fastq, outs=decon/SRR18086342_decon_sing.fastq, ref=contaminants/UniVec.fasta, ref=contaminants/overrep.fasta, ref=phix, ktrim=r, k=21, rcomp=t, mink=11, hdist=2, minlen=200]
Version 38.46

maskMiddle was disabled because useShortKmers=true
0.027 seconds.
Initial:
Memory: max=10290m, total=10290m, free=9966m, used=324m

Added 10506850 kmers; time:     7.036 seconds.
Memory: max=10290m, total=10290m, free=9232m, used=1058m

Input is being processed as paired
Started output streams: 0.036 seconds.
Processing time:        55.800 seconds.

Input:                      1334530 reads       334967030 bases.
KTrimmed:                   7194 reads (0.54%)  1193470 bases (0.36%)
Trimmed by overlap:         95964 reads (7.19%)     7114482 bases (2.12%)
Total Removed:              58776 reads (4.40%)     15820388 bases (4.72%)
Result:                     1275754 reads (95.60%)  319146642 bases (95.28%)

Time:                           62.875 seconds.
Reads Processed:       1334k    21.23k reads/sec
Bases Processed:        334m    5.33m bases/sec
java -Djava.library.path=/cluster/tufts/bio/tools/bcbio/1.1.5/anaconda/opt/bbmap-38.46-0/jni/ -ea -Xmx10g -Xms10g -cp /cluster/tufts/bio/tools/bcbio/1.1.5/anaconda/opt/bbmap-38.46-0/current/ jgi.BBDuk -Xmx10g -tbo -tpe in1=data/SRR18086364_pass_1.fastq in2=data/SRR18086364_pass_2.fastq out1=decon/SRR18086364_decon_1.fastq out2=decon/SRR18086364_decon_2.fastq outs=decon/SRR18086364_decon_sing.fastq ref=contaminants/UniVec.fasta ref=contaminants/overrep.fasta ref=phix ktrim=r k=21 rcomp=t mink=11 hdist=2 minlen=200
Executing jgi.BBDuk [-Xmx10g, tbo, tpe, in1=data/SRR18086364_pass_1.fastq, in2=data/SRR18086364_pass_2.fastq, out1=decon/SRR18086364_decon_1.fastq, out2=decon/SRR18086364_decon_2.fastq, outs=decon/SRR18086364_decon_sing.fastq, ref=contaminants/UniVec.fasta, ref=contaminants/overrep.fasta, ref=phix, ktrim=r, k=21, rcomp=t, mink=11, hdist=2, minlen=200]
Version 38.46

maskMiddle was disabled because useShortKmers=true
0.031 seconds.
Initial:
Memory: max=10290m, total=10290m, free=9913m, used=377m

Added 10506850 kmers; time:     6.257 seconds.
Memory: max=10290m, total=10290m, free=9178m, used=1112m

Input is being processed as paired
Started output streams: 0.156 seconds.
Processing time:        5.335 seconds.

Input:                      59630 reads         14875247 bases.
KTrimmed:                   138 reads (0.23%)   20946 bases (0.14%)
Trimmed by overlap:         10 reads (0.02%)    283 bases (0.00%)
Total Removed:              84 reads (0.14%)    21591 bases (0.15%)
Result:                     59546 reads (99.86%)    14853656 bases (99.85%)

Time:                           11.750 seconds.
Reads Processed:       59630    5.08k reads/sec
Bases Processed:      14875k    1.27m bases/sec
java -Djava.library.path=/cluster/tufts/bio/tools/bcbio/1.1.5/anaconda/opt/bbmap-38.46-0/jni/ -ea -Xmx10g -Xms10g -cp /cluster/tufts/bio/tools/bcbio/1.1.5/anaconda/opt/bbmap-38.46-0/current/ jgi.BBDuk -Xmx10g -tbo -tpe in1=data/SRR18086575_pass_1.fastq in2=data/SRR18086575_pass_2.fastq out1=decon/SRR18086575_decon_1.fastq out2=decon/SRR18086575_decon_2.fastq outs=decon/SRR18086575_decon_sing.fastq ref=contaminants/UniVec.fasta ref=contaminants/overrep.fasta ref=phix ktrim=r k=21 rcomp=t mink=11 hdist=2 minlen=200
Executing jgi.BBDuk [-Xmx10g, tbo, tpe, in1=data/SRR18086575_pass_1.fastq, in2=data/SRR18086575_pass_2.fastq, out1=decon/SRR18086575_decon_1.fastq, out2=decon/SRR18086575_decon_2.fastq, outs=decon/SRR18086575_decon_sing.fastq, ref=contaminants/UniVec.fasta, ref=contaminants/overrep.fasta, ref=phix, ktrim=r, k=21, rcomp=t, mink=11, hdist=2, minlen=200]
Version 38.46

maskMiddle was disabled because useShortKmers=true
0.021 seconds.
Initial:
Memory: max=10290m, total=10290m, free=9859m, used=431m

Added 10506850 kmers; time:     6.260 seconds.
Memory: max=10290m, total=10290m, free=9124m, used=1166m

Input is being processed as paired
Started output streams: 0.035 seconds.
Processing time:        92.165 seconds.

Input:                      2000000 reads       502000000 bases.
KTrimmed:                   3002 reads (0.15%)  460100 bases (0.09%)
Trimmed by overlap:         439534 reads (21.98%)   62037664 bases (12.36%)
Total Removed:              381196 reads (19.06%)   97227296 bases (19.37%)
Result:                     1618804 reads (80.94%)  404772704 bases (80.63%)

Time:                           98.463 seconds.
Reads Processed:       2000k    20.31k reads/sec
Bases Processed:        502m    5.10m bases/sec
java -Djava.library.path=/cluster/tufts/bio/tools/bcbio/1.1.5/anaconda/opt/bbmap-38.46-0/jni/ -ea -Xmx10g -Xms10g -cp /cluster/tufts/bio/tools/bcbio/1.1.5/anaconda/opt/bbmap-38.46-0/current/ jgi.BBDuk -Xmx10g -tbo -tpe in1=data/SRR18091316_pass_1.fastq in2=data/SRR18091316_pass_2.fastq out1=decon/SRR18091316_decon_1.fastq out2=decon/SRR18091316_decon_2.fastq outs=decon/SRR18091316_decon_sing.fastq ref=contaminants/UniVec.fasta ref=contaminants/overrep.fasta ref=phix ktrim=r k=21 rcomp=t mink=11 hdist=2 minlen=200
Executing jgi.BBDuk [-Xmx10g, tbo, tpe, in1=data/SRR18091316_pass_1.fastq, in2=data/SRR18091316_pass_2.fastq, out1=decon/SRR18091316_decon_1.fastq, out2=decon/SRR18091316_decon_2.fastq, outs=decon/SRR18091316_decon_sing.fastq, ref=contaminants/UniVec.fasta, ref=contaminants/overrep.fasta, ref=phix, ktrim=r, k=21, rcomp=t, mink=11, hdist=2, minlen=200]
Version 38.46

maskMiddle was disabled because useShortKmers=true
0.031 seconds.
Initial:
Memory: max=10290m, total=10290m, free=9860m, used=430m

Added 10506850 kmers; time:     6.352 seconds.
Memory: max=10290m, total=10290m, free=9126m, used=1164m

Input is being processed as paired
Started output streams: 0.098 seconds.
Processing time:        88.557 seconds.

Input:                      2000000 reads       502000000 bases.
KTrimmed:                   11350 reads (0.57%)     2233876 bases (0.44%)
Trimmed by overlap:         141514 reads (7.08%)    9911700 bases (1.97%)
Total Removed:              85398 reads (4.27%)     22989670 bases (4.58%)
Result:                     1914602 reads (95.73%)  479010330 bases (95.42%)

Time:                           95.010 seconds.
Reads Processed:       2000k    21.05k reads/sec
Bases Processed:        502m    5.28m bases/sec
java -Djava.library.path=/cluster/tufts/bio/tools/bcbio/1.1.5/anaconda/opt/bbmap-38.46-0/jni/ -ea -Xmx10g -Xms10g -cp /cluster/tufts/bio/tools/bcbio/1.1.5/anaconda/opt/bbmap-38.46-0/current/ jgi.BBDuk -Xmx10g -tbo -tpe in1=data/SRR18091737_pass_1.fastq in2=data/SRR18091737_pass_2.fastq out1=decon/SRR18091737_decon_1.fastq out2=decon/SRR18091737_decon_2.fastq outs=decon/SRR18091737_decon_sing.fastq ref=contaminants/UniVec.fasta ref=contaminants/overrep.fasta ref=phix ktrim=r k=21 rcomp=t mink=11 hdist=2 minlen=200
Executing jgi.BBDuk [-Xmx10g, tbo, tpe, in1=data/SRR18091737_pass_1.fastq, in2=data/SRR18091737_pass_2.fastq, out1=decon/SRR18091737_decon_1.fastq, out2=decon/SRR18091737_decon_2.fastq, outs=decon/SRR18091737_decon_sing.fastq, ref=contaminants/UniVec.fasta, ref=contaminants/overrep.fasta, ref=phix, ktrim=r, k=21, rcomp=t, mink=11, hdist=2, minlen=200]
Version 38.46

maskMiddle was disabled because useShortKmers=true
0.026 seconds.
Initial:
Memory: max=10290m, total=10290m, free=9859m, used=431m

Added 10506850 kmers; time:     6.520 seconds.
Memory: max=10290m, total=10290m, free=9124m, used=1166m

Input is being processed as paired
Started output streams: 0.074 seconds.
Processing time:        75.760 seconds.

Input:                      2000000 reads       502000000 bases.
KTrimmed:                   768 reads (0.04%)   177766 bases (0.04%)
Trimmed by overlap:         118910 reads (5.95%)    19108262 bases (3.81%)
Total Removed:              114844 reads (5.74%)    28963734 bases (5.77%)
Result:                     1885156 reads (94.26%)  473036266 bases (94.23%)

Time:                           82.357 seconds.
Reads Processed:       2000k    24.28k reads/sec
Bases Processed:        502m    6.10m bases/sec
#source ~/.bashrc
module load fastqc
mkdir -p fastqc_decon
fastqc ./decon/*decon*.fastq -o fastqc_decon

#source ~/.bashrc
module load multiqc/1.7.0
mkdir -p multiqc_decon
multiqc ./fastqc_decon -o ./multiqc_decon

Question: Did we get rid of all the adapter sequences? What would your next step be?

Question: Is there a particular tick pool that we may want to remove before assembly?

To be removed before assembly:

  • Ignore single reads
  • Ignore low count reads (SRR18086364)
  • Ignore low quality reads (SRR18091737,SRR18086277)

mkdir -p gooddata

echo SRR18085691 > gooddata.txt
echo SRR18085708 >> gooddata.txt
echo SRR18086342 >> gooddata.txt
echo SRR18086575 >> gooddata.txt
echo SRR18091316 >> gooddata.txt


cat gooddata.txt | while read $line; do cp decon/$line*1.fastq gooddata; cp decon/$line*2.fastq gooddata; done

This concludes Part I, please come back after the break for Part II - using a wrapper script to bin your data.


Part II

Running an Assembly on the Cleaned Data

This command takes approximately 20 minutes, so the commands used to make the assembly are commented out.



#/cluster/tufts/bio/tools/megahit/1.2.9/bin/megahit  -m 16000000 -t 32 --read ./gooddata/* \
#--k-list 21,41,61,81,99 \
#--no-mercy \
#--min-count 2 \
#-o megahit_out/

Megahit: de Bruijn graph Assembly

Megahit workflow

What is a deBruijn graph?

It is an assembly algorithm that splits your sequence into k-mers and tries to build the longest contigs along the shortest parsimonious path.

Megahit workflow

To save time in the workshop, the assembly has been done using the commented out command above and placed into your workshop folder called “reports”.

Checking the quality of our Assembly

Quast is a commonly used tool to assess assemblies. It will provide a report that is either in a text file or an html.

Let’s run the following command and then look for the quast report to see if we have a “good” assembly.


/cluster/tufts/bio/tools/quast/5.2.0/quast.py -o quast_assembly ./reports/final.contigs.fa
/cluster/tufts/bio/tools/quast/5.2.0/quast.py -o quast_assembly ./reports/final.contigs.fa

Version: 5.2.0, 3d87c606

System information:
  OS: Linux-3.10.0-1127.el7.x86_64-x86_64-with-redhat-7.8-Maipo (linux_64)
  Python version: 2.7.5
  CPUs number: 72

Started: 2022-11-09 11:19:20

Logging to /cluster/home/arhode05/Metagenomics2022/quast_assembly/quast.log
NOTICE: Maximum number of threads is set to 18 (use --threads option to set it manually)

CWD: /cluster/home/arhode05/Metagenomics2022
Main parameters: 
  MODE: default, threads: 18, min contig length: 500, min alignment length: 65, min alignment IDY: 95.0, \
  ambiguity: one, min local misassembly length: 200, min extensive misassembly length: 1000

WARNING: Can't draw plots: python-matplotlib is missing or corrupted.

Contigs:
  Pre-processing...
  ./reports/final.contigs.fa ==> final.contigs

2022-11-09 11:19:22
Running Basic statistics processor...
  Contig files: 
    final.contigs
  Calculating N50 and L50...
    final.contigs, N50 = 876, L50 = 7401, auN = 2787.5, Total length = 21673500, GC % = 53.33, # N's per 100 kbp =  0.00
Done.

NOTICE: Genes are not predicted by default. Use --gene-finding or --glimmer option to enable it.

2022-11-09 11:19:23
Creating large visual summaries...
This may take a while: press Ctrl-C to skip this step..
  1 of 1: Creating Icarus viewers...
Done

2022-11-09 11:19:24
RESULTS:
  Text versions of total report are saved to /cluster/home/arhode05/Metagenomics2022/quast_assembly/report.txt, report.tsv, and report.tex
  Text versions of transposed total report are saved to /cluster/home/arhode05/Metagenomics2022/quast_assembly/transposed_report.txt, transposed_report.tsv, and transposed_report.tex
  HTML version (interactive tables and plots) is saved to /cluster/home/arhode05/Metagenomics2022/quast_assembly/report.html
  Icarus (contig browser) is saved to /cluster/home/arhode05/Metagenomics2022/quast_assembly/icarus.html
  Log is saved to /cluster/home/arhode05/Metagenomics2022/quast_assembly/quast.log

Finished: 2022-11-09 11:19:24
Elapsed time: 0:00:04.007177
NOTICEs: 2; WARNINGs: 1; non-fatal ERRORs: 0

Thank you for using QUAST!

Using Kraken to check for Metagenome Composition

At this point, we may be interested in whether our assembly makes sense for our set of contigs.

Kraken2 is the newest version of Kraken, a taxonomic classification system using exact k-mer matches. This k-mer based approach has very fast classification speeds with high accuracy.

This approach differs from homology based approaches that try to match sequences to each other and score them based on the number of mismatches, deletions and inserts. Kraken uses the entire kmer composition of the contig to match it to a database where reference sequences have been broken down into kmer “hashes” or a database of what the kmers look like for a particular organism.


/cluster/tufts/bio/tools/conda_envs/kraken/2.1.2/bin/kraken2 --use-names --threads 4 --db /cluster/tufts/bio/tools/training/metagenomics/kraken_virus --report kraken.report.txt --quick reports/final.contigs.fa --classified-out classified_sequences.tsv > sequences.kraken
Loading database information... done.
48954 sequences (31.42 Mbp) processed in 0.473s (6215.0 Kseq/m, 3988.65 Mbp/m).
  44345 sequences classified (90.59%)
  4609 sequences unclassified (9.41%)

head classified_sequences.tsv
>k141_13788 flag=1 multi=2.0000 len=335 kraken:taxid|283
TGACGGCGAAGAGGGCGAGGTCAACCGCCTGCAGTTTGCACCGCCCTTTGGCGAGAAGGAGACGATGCGCATCGTGCTGCCCCAGGGCTTCAAGGACGAATCGGACCGGCCGCTGGCCAATGCCAACCTGTTCCCGCTGCAGGTGCAAAGCGGCCTGATGCCGCCGCTGGCCAAGTTTGCCGCCTCGCCCTTTGGCGTGGTCGAGCGCTTTGCCGAAGGCGACAAGGGCCCGGCGATGTTCCCGGTGACCCTGCGCAATGTGGAGCAGGACCTGCAGATCCAGGGCTTGTCGATCGAGGACAAGGGCACCGTCTCGACCCTGCAGCTGCAAAGCG
>k141_36756 flag=1 multi=4.0000 len=1049 kraken:taxid|568
CCTCATGGAGATTTACCAAATGGCTAAGGCAAAACTTAACCCGTTAGCAACTTTATTGCGCGGGGGGCTTTGCGTACCGTTATTCATCGCAGCAGCACCAGTGATGGCCGCGGAAGGGGACGACGTGATGGTTGTCACCGCTTCAGCAACAGAACAAAACCTGAAAGATGCACCTGCCAGTATTAGCGTGATTACGCGTGAAGACTTGGCTAAAAAGCCGATTCAGAACCTGAAGGACATTCTGCAAGAAGTCCCAGGCGTACAGCTGACTAACGAAGGTGATAACCGCAAGGGCGTGAGTATCCGTGGTTTGGACAGTAGCTATACGCTGATTTTGGTGGATGGCAAACGCGTCAGCTCACGTACGGCGGTGTTCCGTCATAACGACTATGACCTAAGCTGGGTGCCCGCCGAGGCGATTGAGCGTATCGAAGTGGTGCGCGGCCCAATGTCTTCGCTTTACGGCTCTGATGCTTTAGGCGGCGTAGTGAACATTATTACCCGTAAAGTGGGTAAAGAGTGGCACGGTTCCCTGAGTGCCGATAGCACTATTCAGGAACACCGCGATCGCGGCGATAGCTATAACGGCAGCTTCTATACCAGTGGCCCGTTGATTGATGATGTGCTCGGAGTAAAAGTCTTTGGCAATTTGGGCAAGCGCGAAAAAGATGATGCCCAGAAATCGACGACCAGCAAATCGGGCGAATCGGGGCGCATAGAAGGGTACACCACGCGTGATGCTAACGTTGAGTTCGCATGGACGCCAGAAGCGAATCAGGACATGACCTTTGGCTACGGTTTTGACCGTCAGGATCGTGATTCTGATTCTTTGGATAAAAACCGTCTGGAACGTCAAAACTATTCAATTGGTCACAACGGGCGTTGGGATTTAGCGAACACCGAAATTCGCGCCTATGGTGAAAAGATTGATAACTACAACGAAAATCGTATCACGGCGAAAAATAACGCCATCGACGGGAAAGTTGTTGTGCCCCTCGGTGAGCTGAATCAGCTATTCACACTGGGTGGTGAATACCGTAACGATAAAC
>k141_36757 flag=1 multi=2.0000 len=346 kraken:taxid|1907578
TCTCATGGAAGCGTTCCAGTAAGGCTTCAGCGGCCAGCAGCGAGAAACCGCGCGCTTCACGGTTGCCGGTCAGACGCCAGGCCGCCACGCACGACAGGGTATACAGAAAGCCCAAATCGTGAGTATTGGTGTCGTTGCGCCCGGCGATGCGCAGGCCAAACGAGCGCACATTTTTCTCGGCAAGCTGGCGGAATTTTTCGTCGCCGCTCATCTCCCACGCCAGCCACAGCTGCCCGGTCCAGAAGCTGGTGGTCCACTCGACGTTGTCCGTCAGCGGGTAGAACCCATCCTCACAGGTTTCCGCCGGGAATTTTTCACCGAACTCCGTTAAATGACGGCTAATCAG
>k141_13790 flag=1 multi=2.0000 len=331 kraken:taxid|286
CGCTTTGCACTTGCACGTCGATGGCGTTTTCCAAGCCGTCGGGGAACAGGTAGTGGTGGTCGGCCGCCGTGGTGCAGCCCGACAGCAACAATTCGGCCAGCGCGACTTTAGTGGCGAGGGCGAGTTTTTCCGGGGTAAGCCGGGCCCAGACCGGGTACAGGGTTTTCAGCCACGGGAACAACGGTTGGTTGACCACCGGCGCCCAGGCGCGGGTCAGGGTTTGATAGAAGTGGTGATGGGTGTTGATCAGGCCCGGCAGGATTACGTGCTGGCGAGCGTCGAATATGTTTTCGCAAGGTACCGAGGGTTCGCGTCCCCAGCCCAGCACTTC
>k141_13791 flag=1 multi=3.0000 len=771 kraken:taxid|106649
GCAATCTTGTTTATATTTCATGGCATTTTTCTGTTGTTTTTATTGAGACCTCAATCAAAACGCAATTTAGCTCAAAATGCAGATGAATATTTGATTGTATATGCAAGTCAGTCAGGGCAGACAGAAAGTTTTGCTTTGCAAATAGCCCAGCAATTATCTGCTTCAGGTTATTTGGTTCAGTGCTTGAGTATTGAACAAGTGAATGCTGCTTTATTCAAACATGGGACAAAGATTTTATGGATCGTCAGTACTTATGGCGAGGGGGATGCACCAGATTCGGCACGTCATTTTGTTGGGAATGTAATGACAAAGTCATTTGATTTAAATCACATTGAGTATGCTGTGTTGGCTTTTGGTGATTCGCATTATGCAAATTTCTGTAATTTTGGTAGACAATTGGATTTATGGTTAACTGAAAACCATGCACAAGCTTTATTTCCCATGATTTGTGTTGATCAACTAAACCCTACAGGTCTGACGGAATGGCAAACTCAACTTAACCTAGTTTTGCCGCAATTTTCCGTTCAATCTGTTCAATTGAAACAATATCCTTTTCATTCCGTGGTTTTATCTGAACGCCATTTGTTAAATCAAGGCAGTTTAGGGCATCCAATGTATCATCTTGTGTTTACCCAAGTTGAAGCATTATGTTGGAAATCTGGTGATATTCTTGAAATTCAATGTGCCAATACAGATTCACAAATCAAGGCATTTTTAGATCATTTTAATCTTCAAAACTCCAGTGTGTTTCAGGCTAATCATCCAATAGCG

We can open up the sequence report inside RStudio OnDemand and scroll through the findings.

This can be a very long list of species names, so it may be more helpful to use an interactive visualization tool to look at our data.

Krona is a very useful tool that can take in a variety of formats. In this case, we are providing our kraken.report to the visualization. Metabarcoding data assigned to a taxonomy can also be used in this case.


/cluster/tufts/bio/tools/conda_envs/kraken/2.1.2/bin/ktImportTaxonomy -t 5 -m 3 -o krona.html kraken.report.txt
   [ WARNING ]  Score column already in use; not reading scores.
   [ WARNING ]  The following taxonomy IDs were not found in the local
                database and were set to root (if they were recently added to
                NCBI, use updateTaxonomy.sh to update the local database):
                28883 541000 2705459 143813 2546450 741091
Loading taxonomy...
Importing kraken.report.txt...
Writing krona.html...

The output, when opened in a web browser, allows the user to interact with the data and explore different levels of the data.

Krona output

What can we do with Metagenomic Approaches

Case Study: Describing a Complete Cyanobacterial Genome and its Symbionts from an Extremely Arid Environment

The Atacama Desert - Are we on Mars?

Atacama Desert

So we are probably running out of time to continue working hands on.

Let’s take some time to discuss what the next steps might look like.

This discussion will center around a recent project from Dr. Pearson’s lab, conducted by Neveda Naz, Ph.D.

Neveda builds little robots and sends them to outerspace. (Neveda if you are here, feel free to comment!)

Please open up this pdf here to find the discussion.

Helpful Resources

Also, for future reading, I have placed two useful .pdf’s in our public github pages that summarize the steps we are discussing in further detail.

Essentials in Metagenomics I Essentials in Metagenomics II

This markdown and associated files will be placed in our Github and mailed out to the class shortly.

We will also send out a video of this workshop.

Please Provide Feedback

Jason and I hope to continue developing this practical material to provide more hands-on experience in the future, so any feedback on the tools you would like to explore is appreciated.

LS0tCnRpdGxlOiAiTWV0YWdlbm9taWNzIFdvcmtzaG9wLCBOb3ZlbWJlciA5LCAyMDIyIgphdXRob3I6ICJBZGVsYWlkZSBSaG9kZXMgUGguRC4iCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKICAgIGRmX3ByaW50OiBwYWdlZAogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHllcwotLS0KCiMjIEludHJvZHVjdGlvbiBhbmQgQmFja2dyb3VuZAoKIyMjIEFnZW5kYQoKIyMjIyBQYXJ0IEkgLSBTZXR0aW5nIHVwIHRoZSBEYXRhCgoqIERlZmluZSB0aGUgZGlmZmVyZW5jZXMgYmV0d2VlbiBNZXRhYmFyY29kaW5nL0FtcGxpY29uIHNlcXVlbmNpbmcgYW5kIFdob2xlIFNob3RndW4gU2VxdWVuY2luZyBNZXRhZ2Vub21pY3MKKiBHZXQgc29tZSBwcmFjdGljZSBpbiBSU3R1ZGlvIE9uRGVtYW5kIGFuZCB1c2luZyB0aGUgVHVmdHMgQ2x1c3RlcgoqIExlYXJuIGFib3V0IGFjY2Vzc2luZyBpbnRlcmVzdGluZyBOQ0JJIGRhdGEgdGhyb3VnaCBCaW9Qcm9qZWN0cyBhbmQgU1JBIFJ1biBTZWxlY3RvcgoqIFJlZmluZSBvdXIgcXVhbGl0eSBjb250cm9sIGJlc3QgcHJhY3RpY2VzIHRvIHByZXByb2Nlc3MgZGF0YSB3ZSBoYXZlIGdlbmVyYXRlZCBvciBkb3dubG9hZGVkCisgRmFzdHFjCisgTXVsdGlxYworIEttZXItYmFzZWQgZmlsdGVyaW5nIGFuZCB0cmltbWluZyB3aXRoIEJDQmlvIHRvb2xzCgojIyMjIFBhcnQgSUkgLSBQcmFjdGljZSBhIHR5cGljYWwgbWV0YWdlbm9taWMgd29ya2Zsb3cKCisgTWV0YWdlbm9tZSBBc3NlbWJseSB3aXRoIE1lZ2FoaXQKKyBBc3Nlc3NpbmcgdGhlIFF1YWxpdHkgb2YgYW4gQXNzZW1ibHkgd2l0aCBRdWFzdAorIFByZWxpbWluYXJ5IGNvbnRhbWluYXRpb24gc2NyZWVuaW5nIHdpdGgga3Jha2VuCisgVmlzdWFsaXphdGlvbiBvZiBrcmFrZW4gcmVwb3J0cyB3aXRoIHRoZSBrcm9uYSB0b29sCgoKVGhlIGZvbGxvd2luZyBpdGVtcyBhcmUgbm90IGhhbmRzIG9uLCBidXQgd2lsbCBiZSBzaG93biBhcyBwYXJ0IG9mICB1c2UgY2FzZSBvZiBhIHJlY2VudCBNZXRhZ2Vub21pY3MgV29ya2Zsb3cgZG9uZSBpbiBjb2xsYWJvcmF0aW9uIHdpdGggYSBUdWZ0cyBSZXNlYXJjaGVyCgorIE1ldGFnZW5vbWUgQmlubmluZyBhbmQgUmVmaW5lbWVudCB3aXRoIE1ldGFCYXQyLCBNYXhCaW4gYW5kIENvbmNvY3QKKyBWaXN1YWxpemF0aW9uIG9mIFNlcXVlbmNlIG9mIE1ldGFnZW5vbWljIEJpbnMgd2l0aCBCbG9iVG9vbHMKKyBFeHRyYWN0aW5nIFJlbGV2YW50IFJlYWRzIHdpdGggQldBCisgUmVhc3NlbWJseSB3aXRoIE1lZ2FoaXQgZnJvbSB0aGUgQmlucworIFRheG9ub21pYyBDbGFzc2lmaWNhdGlvbiB3aXRoIEthaWp1CisgRnVuY3Rpb25hbCBDbGFzc2lmaWNhdGlvbiB3aXRoIFByb2trYQoKSWYgdGhpcyBzb3VuZHMgbGlrZSBhIGxvdCBvZiBncm91bmQgdG8gY292ZXIsIHlvdSBhcmUgY29ycmVjdCEKCkluIHNvbWUgcG9ydGlvbnMgb2YgdGhpcyB0dXRvcmlhbCwgd2UgZG9uJ3QgYWN0dWFsbHkgcnVuIHRoZSBjb2RlLCBidXQganVtcCBhaGVhZCB0byB0aGUgbmV4dCBzdGVwLgoKRm9yIHRoZXNlICJza2lwcGVkIiBwb3J0aW9ucywgdGhlIGNvZGUgdG8gcnVuIHRoZSBwcm9jZXNzIGlzIHByb3ZpZGVkLgoKLS0tIAoKIyMjIEF0dGFjaCBwdWJsaWMgbGlicmFyeSBwYXRocyB0byB5b3VyIFJTdHVkaW8gT25EZW1hbmQgc2Vzc2lvbgoKVGhlIHNldHVwIGNvZGUgYWRkcyB0aGUgbGlicmFyaWVzIGluIHRoZSBvcmRlciB0aGV5IHdpbGwgYmUgc2VhcmNlZCBmb3IgcGFja2FnZXMuIAoKU2V0dGluZyBgLmxpYnBhdGhzKClgIHRvIFR1ZnRzIHNoYXJlZCBmb2xkZXJzIGNhbiByZWR1Y2UgdGhlIGFtb3VudCBvZiB0aW1lIHNwZW50IGRvd25sb2FkaW5nIHBhY2thZ2VzLiAKCioqUGxlYXNlIHJlYWNoIG91dCB0byB1cyBhYm91dCBhbnkgZGlmZmljdWx0IG9yIHRyaWNreSBpbnN0YWxscywgc29tZXRpbWVzIGl0IGlzIGEgbGlicmFyeSBwYWNrYWdlIGVycm9yIHRoYXQgaGFzIHRvIGJlIGZpeGVkIGJ5IGFuIFRUUyBIUEMgUmVzZWFyY2ggVGVjaG5vbG9neSBTcGVjaWFsaXN0LioqCgpQbGVhc2UgbWFrZSBzdXJlIHRoYXQgdGhlIG91dHB1dCB0byB0aGlzIGNvZGUgY2h1bmsgaGFzIHRoZSBzaGFyZWQgbGlicmFyeSwgIi9jbHVzdGVyL3R1ZnRzL2hwYy90b29scy9SLzQuMC4wIiAgaW4gcG9zaXRpb24gWzFdCgpFeGFtcGxlIG91dHB1dCAoaXQgZGVwZW5kcyB3aGF0IGVsc2UgeW91IGhhdmUgYmVlbiBkb2luZyBpbiBSU3R1ZGlvIGJlZm9yZSB0b2RheSkuCgpbMV0gIi9jbHVzdGVyL3R1ZnRzL2hwYy90b29scy9SLzQuMC4wIgpbMl0gIi9jbHVzdGVyL2hvbWUvYXJob2RlMDUvUi94ODZfNjQtcGMtbGludXgtZ251LWxpYnJhcnkvNC4wIgpbM10gIi9vcHQvc2hhcmVkL1IvNC4wLjAvbGliNjQvUi9saWJyYXJ5IiAKCgpDb21tYW5kcyB0byBzcGVjaWZ5IHRoZSBzaGFyZWQgZGlyZWN0b3J5IGFzIHRoZSBmaXJzdCBwbGFjZSB0byBsb29rIGZvciBSIGxpYnJhcmllcyBhbmQgY2hlY2sgdGhlIG91dHB1dC4KCmBgYHtyIGNoZWNrIGxpYnJhcnkgcGF0aHMsIGV2YWw9RkFMU0V9CgoKLmxpYlBhdGhzKGMoJy9jbHVzdGVyL3R1ZnRzL2hwYy90b29scy9SLzQuMC4wJywubGliUGF0aHMoKSkpCgoubGliUGF0aHMoKQoKYGBgCgoKCgojIyMgVGhpcyBNZXRhZ2Vub21pY3MgVHV0b3JpYWwgaXMgbWFpbmx5IGEgc2V0IG9mIEJhc2ggQ29tbWFuZHMKClRoaXMgdHV0b3JpYWwgdXNlcyBjb2RlIGNodW5rcy4gVG8gcnVuIGFuIGluZGl2aWR1YWwgY29kZSBjaHVuayB3aGlsZSB0aGUgbm90ZWJvb2sgaXMgb3BlbiBpbiBPbkRlbWFuZCBSU3R1ZGlvLCBwbGVhc2UgcHJlc3MgdGhlIGdyZWVuIHRyaWFuZ2xlIG9uIHRoZSB1cHBlciByaWdodCBjb3JuZXIgb2YgdGhlIGNvZGUgY2h1bmsuCgoKYGBge3Igc2V0dXAgY29tbWFuZHMsIHNldHVwLCBpbmNsdWRlPUZBTFNFfQoKI1RoaXMgY29tbWFuZCBzZXRzIG91ciB3b3JraW5nIGRpcmVjdG9yeSB0byB0aGlzIHdvcmtzaG9wCmtuaXRyOjpvcHRzX2tuaXQkc2V0KHJvb3QuZGlyID0gJ34vTWV0YWdlbm9taWNzMjAyMicpCgojVGhlIG5leHQgdHdvIGxpbmVzIG1ha2VzIG91ciBiYXNoIHByb2ZpbGUgdmlzaWJsZSB0byB0aGUgUiBlbnZpcm9ubWVudCwgYWxsb3dpbmcgdGhlIHVzZSBvZiBtb2R1bGVzLgprbml0cjo6b3B0c19jaHVuayRzZXQoZW5naW5lLm9wdHMgPSBsaXN0KGJhc2ggPSAiLWwiKSkKU3lzLnNldGVudihCQVNIX0VOVj0ifi8uYmFzaHJjIikKCmBgYAoKWW91IG1heSBiZSB3b25kZXJpbmcgd2h5IHdlIHdlbnQgdGhyb3VnaCB0aGUgdHJvdWJsZSBvZiBoYXZpbmcgYmFzaCBjb21tYW5kcyBpbnNpZGUgYW4gUiBub3RlYm9vayBmb3IgdGhpcyB0dXRvcmlhbC4gVGhlIHNpbXBsZXN0IGFuc3dlciBpcyB0aGF0IFJTdHVkaW8gaGFzIHRoZSBoYW5keSBhYmlsaXR5IHRvIG9wZW4gdmlzdWFsaXphdGlvbiBmaWxlcyB3aXRoIGEgc2ltcGxlIGNsaWNrIG9uIHRoZSBmaWxlIG5hbWUgaW4gdGhlICBsb3dlciByaWdodCBzY3JlZW4uIFRoaXMgc2F2ZXMgYSBsb3Qgb2YgdGltZSBhbmQgY29uZnVzaW5nIG5hdmlnYXRpb24gd2hlbiBkb2luZyB0aGlzIHR5cGUgb2YgcHJvamVjdCwgdGhhdCBwcm9kdWNlcyBhIGxvdCBvZiBpbnRlcm1lZGlhdGUgZmlsZXMuCgpSU3R1ZGlvIGNhbiBydW4gY29kZSBjaHVua3MgaW4gb3RoZXIgbGFuZ3VhZ2VzIGJ5IHJlc2V0dGluZyB0aGUgY29kZSBjaHVua3MgdG8gcmVhZCB0aGF0IGxhbmd1YWdlLgoKKiAgIGB7YmFzaH1gIGluZGljYXRlcyB0aGF0IHRoZSBjb2RlIGNodW5rIGlzIGluIGNvbW1hbmQgbGluZSBzeW50YXgsIHNvIHRoZXNlIGNvbW1hbmRzIGNhbiBiZSBjb3BpZWQgYW5kIHBhc3RlZCBkaXJlY3RseSBpbnRvIGEgdGVybWluYWwKCiogICBge3J9YCBpbmRpY2F0ZXMgdGhhdCB0aGUgY29kZSBjaHVuayB1c2VzIFItY29kZQogICAgClRvIHNhdmUgYSBidW5jaCBvZiBjb3B5aW5nL3Bhc3RpbmcsIHdlIGFyZSBqdXN0IGdvaW5nIHRvIHJ1biBib3RoIHR5cGVzIG9mIHRoZXNlIGNodW5rcyBpbnNpZGUgb3VyIG5vdGVib29rIHVzaW5nIFJTdHVkaW8gT25EZW1hbmQuCgpUaGUgb3JkZXIgb2YgY2h1bmtzIGlzIGltcG9ydGFudCwgc28gaWYgeW91IHNraXAgb25lIG9yIGdldCBsb3N0LCBpdCBpcyBwb3NzaWJsZSB0byB1c2UgdGhlIGRyb3Bkb3duIG1lbnUgbmV4dCB0byB0aGUgd29yZCAiUnVuIiBhdCB0aGUgdG9wIG9mIHRoaXMgd2luZG93IHRvIHJ1biBtdWx0aXBsZSBjaHVua3MgdG8gZ2V0IHlvdSBiYWNrIHRvIHdoZXJlIHlvdSBzdGFydGVkLgoKQW55IHF1ZXN0aW9ucz8KCi0tLQoKIyMjIyMgV2hhdCBvdGhlciAia2VybmVscyIgYXJlIGF2YWlsYWJsZSBpbiBSIG5vdGVib29rIGNvZGUgY2h1bmtzPyAoSGludCAtIGNsaWNrIHRoZSBkb3duIGFycm93IG5leHQgdG8gdGhlICJJbnNlcnQgQ2h1bmsgY29tbWFuZCBhdCB0aGUgdG9wIG9mIHRoaXMgd2luZG93KQoKLS0tCgoKIyMjIE1vZHVsZXMgYW5kIENvbmRhIEVudmlyb25tZW50cwoKSW4gdGhpcyB3b3Jrc2hvcCwgd2Ugd2lsbCBzb21ldGltZXMgYmUgbG9hZGluZyBtb2R1bGVzIGZyb20gdGhlIEhQQyB0byB1c2UgaW4gYSBjb2RlIGNodW5rLgoKSGVyZSBpcyBhbiBleGFtcGxlIGNvZGUgY2h1bmsgdGhhdCBsb2FkcyBhIG1vZHVsZSBmb3Igc2FtdG9vbHMgYW5kIHJ1bnMgdGhlIGNvbW1hbmQgd2l0aCB0aGUgaGVscCBmbGFnIHRvIGdlbmVyYXRlIHNvbWUgb3V0cHV0IHRvIHRlc3QgdGhhdCB0aGUgbW9kdWxlIGxvYWRlZCBjb3JyZWN0bHkuCgpJZiB0aGUgYmFzaCBlbnZpcm9ubWVudCBpcyBub3QgZGVzaWduYXRlZCBpbiB0aGUgc2V0dXAgY2h1bmssIHlvdSBtYXkgbmVlZCB0byBhZGQgdGhpcyBiYXNoIGNvbW1hbmQgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgY2h1bmsgdG8gZW5hYmxlIG1vZHVsZSBsb2FkaW5nLiAKCmBzb3VyY2Ugfi8uYmFzaHJjYAoKYGBge2Jhc2ggZXhhbXBsZSBtb2R1bGUgY29tbWFuZCwgcmVzdWx0cz0naGlkZSd9Cgptb2R1bGUgbG9hZCBzYW10b29scy8xLjkKc2FtdG9vbHMgLS1oZWxwCgpgYGAKCgpUaGUgYmVoYXZpb3Igb2YgbW9kdWxlcyBpbiB0aGUgY29kZSBjaHVua3MgZGlmZmVycyBmcm9tIG91ciBkaXJlY3QgY29tbWFuZCBsaW5lLgoKVGhlIFJtYXJrZG93biBub3RlYm9vayB3aWxsIG5vdCByZW1lbWJlciBpdCBmcm9tIGNodW5rIHRvIGNodW5rLiBTbyBsb2FkIHRoZSBtb2R1bGVzIGluIHRoZSBjaHVua3Mgd2hlcmUgdGhlIGNvbW1hbmRzIGFyZSBuZWVkZWQuCgpBbiBleGFtcGxlIHdpdGggY29uZGEgZW52aXJvbm1lbnRzIHdpbGwgYmUgc2hvd24gaW4gUGFydCBJSS4KCi0tLQoKIyMjIyMgV2hhdCBoYXBwZW5zIHdoZW4geW91IHJ1biB0aGlzIGNodW5rPwoKYGBge2Jhc2h9Cgptb2R1bGUgbGlzdAoKYGBgCgotLS0KCiMjIyMjIFdoeSB1c2UgbW9kdWxlcyBpbnN0ZWFkIG9mIGNvbmRhIGVudmlyb25tZW50cz8KCiogICBDb25kYSBlbnZpcm9ubWVudHMgYXJlIGdyZWF0IGZvciBpbnN0YWxsaW5nIHNwZWNpZmljIHZlcnNpb25zIG9mIHByb2dyYW1zLCBidXQgb2Z0ZW4gYnJpbmcgaW4gY2xhc2hpbmcgZGVwZW5kZW5jaWVzLCBhbmQgb25seSBvbmUgaXMgYWN0aXZlIGF0IGEgdGltZS4KCiogICBVc2luZyBIUEMgbW9kdWxlcyBjYW4gcHJvdmlkZSBtb3JlIGludGVncmF0aW9uIGJlY2F1c2UgeW91IGNhbiBsb2FkIHNldmVyYWwgYXQgb25lIHRpbWUuCgoqICAgT2YgY291cnNlLCBjb25kYSBlbnZpcm9ubWVudHMgY291bGQgYmUgdXNlZCBpZiB5b3UgbG9hZCBhbGwgdGhlIHJlcXVpcmVkIHByb2dyYW1zIGludG8gdGhlIHNhbWUgZW52aXJvbm1lbnQuIFdlIHdpbGwgc2VlIGFuIGV4YW1wbGUgb2YgdGhpcyBsYXRlciB3aXRoIE1ldGF3cmFwCgoKIyMgSW50cm9kdWNpbmcgdGhlIERhdGEgLSBHaWFudCBQYW5kYSB0aWNrcwoKVGlja3MgYXJlIGNhcGFibGUgb2Ygc3ByZWFkaW5nIHBhdGhvZ2VucyAodmlydXNlcywgYmFjdGVyaWEgYW5kIG90aGVyIHBhcmFzaXRlcykgYW1vbmcgYSBob3N0IHBvcHVsYXRpb24uIE5vdCBtdWNoIGlzIGtub3duIGFib3V0IHRoZSBzcHJlYWQgb2YgdGljay1ib3JuZSB2aXJ1c2VzIGluIEdpYW50IFBhbmRhcy4gVGhlIGRlbnNpdHkgb2YgZ2lhbnQgcGFuZGFzIGluIGJyZWVkaW5nIGNhcHRpdml0eSBpbiBTaWNodWFuIFByb3ZpbmNlLCBDaGluYSBtYXkgbGVhZCB0byBtb3JlIHRyYW5zbWlzc2lvbiBvZiB0aGVzZSBkaXNlYXNlcy4gVGhlIHJlc2VhcmNoZXJzIHdobyBsb2FkZWQgdGhpcyBkYXRhIGludG8gdGhlIFNSQSB3ZXJlIGludGVyZXN0ZWQgaW4gY2hhcmFjdGVyaXppbmcgdGhlIHZpcm9tZSBvZiB0aGVzZSB0aWNrcyBhbmQgdG8gY29tcGFyZSB0aGVzZSB3aXRoIHRoZSB2aXJvbWUgb2YgdGhlIHBhbmRhcy4KCldlIGFyZSBub3QgZ29pbmcgdG8gcmVzdHJpY3Qgb3VyIGFuYWx5c2lzIHRvIHRoZSB2aXJvbWUsIGFuZCBqdXN0IHRha2UgYSBnZW5lcmFsIGxvb2sgYXQgd2hhdCB0aGVzZSB0aWNrcyBhcmUgY2FycnluZyBhcm91bmQgaW4gZ2VuZXJhbCB1c2luZyBwcmFjdGljYWwgbWV0YWdlbm9taWNzIHdvcmtmbG93cy4KCltDaGVjayBvdXQgdGhlIGJpb3Byb2plY3QgaGVyZV0oaHR0cHM6Ly93d3cubmNiaS5ubG0ubmloLmdvdi9iaW9wcm9qZWN0L1BSSk5BODA4NzkzKSAKCltDaGVjayBvdXQgdGhlIGZpbmFsIHBhcGVyIGhlcmVdKGh0dHBzOi8vam91cm5hbHMuYXNtLm9yZy9kb2kvMTAuMTEyOC9zcGVjdHJ1bS4wMjAzNC0yMikKCgohW0lzIGhlIHNsZWVweSBvciBpcyBoZSBzaWNrPyBcbGFiZWx7R2lhbnQgUGFuZGEgfV0oLi9pbWFnZXMvc2xlZXB5X3BhbmRhLnBuZyl7d2lkdGg9NTAlfQoKCldlIGFyZSBnb2luZyB0byBicmluZyBpbiBzb21lIG9mIHRoZSBkYXRhIGZyb20gdGhpcyBiaW9wcm9qZWN0IHRvIG91ciBNZXRhZ2Vub21pY3MgVHV0b3JpYWwgc3BhY2UuCgojIyMjIFdoYXQgaW5mb3JtYXRpb24gY2FuIHdlIGZpbmQgaW4gdGhlIG1ldGFkYXRhPwoKU1JBIE1ldGFkYXRhIC0gZXZlcnkgcHJvamVjdCBpcyBkaWZmZXJlbnQhCgpFeGFtcGxlIGZyb20gQmlvUHJvamVjdCBbTWljcm9iZXMgRnJvbSBNdW1dKGh0dHBzOi8vd3d3Lm5jYmkubmxtLm5paC5nb3YvVHJhY2VzL3N0dWR5Lz9xdWVyeV9rZXk9MTEmV2ViRW52PU1DSURfNjM2YjZmNTU1ZTM0NjE3Yzg1NzZkYjhmJm89YWNjX3MlM0FhKQoKCiFbTXVtIHNwb25nZSBtZXRhZGF0YSBcbGFiZWx7VGljayBNZXRhZGF0YSB9XSguL2ltYWdlcy9tdW1fbWV0YWRhdGEucG5nKXt3aWR0aD03MCV9CgoKCltUaGUgTWV0YWRhdGEgZnJvbSBvdXIgQmlvUHJvamVjdF0oaHR0cHM6Ly93d3cubmNiaS5ubG0ubmloLmdvdi9UcmFjZXMvc3R1ZHkvP3F1ZXJ5X2tleT0xNSZXZWJFbnY9TUNJRF82MzZiNmY1NTVlMzQ2MTdjODU3NmRiOGYmbz1hY2NfcyUzQWEpCgoKIVtQYW5kYSB0aWNrIG1ldGFkYXRhIFxsYWJlbHtUaWNrIE1ldGFkYXRhIH1dKC4vaW1hZ2VzL3RpY2tfbWV0YWRhdGEucG5nKXt3aWR0aD03MCV9CgojIyMjIyBRdWVzdGlvbiAtIFdoeSBkbyBtb3N0IG9mIHRoZSByZWFkcyBvZiAic3BvdCBsZW5ndGgiIGVxdWFsIHRvIDUwMj8KClNvbWV0aGluZyB5b3UgbWF5IGhhdmUgbm90aWNlZCBpcyB0aGF0IHRoZSByZWFkcyBhcmUgc3VzcGljaWFsbHkgZXZlbiBpbiBudW1iZXIsIGF0IGxlbmd0aCA1MDIuIFRoZSBleHBlcmltZW50YWwgZGVzaWduIHN0YXRlcyB0aGF0IHRoZSByZWFkcyB3ZXJlIHBhaXJlZC1lbmQgMngyNTAuCgoKIyMjIyMgUXVlc3Rpb24gLSBXaG8gaXMgcmVzcG9uc2libGUgZm9yIGxvYWRpbmcgQmlvUHJvamVjdCBtZXRhZGF0YSB0byB0aGUgTkNCST8KCgojIyMgT2J0YWluaW5nIERhdGEgZnJvbSBTUkEKClRoZSBkYXRhIHdlIGFyZSBnb2luZyB0byBjb3B5IG92ZXIgY2FuIGJlIG9idGFpbmVkIGRpcmVjdGx5IGZyb20gdGhlIFNSQSBieSB1c2luZyBvdXIgY29tbWFuZCBsaW5lIG1vZHVsZSBmb3IgdGhlIFNSQVRvb2xraXQuIFRoaXMgY2FuIHRha2UgYSBsaXR0bGUgd2hpbGUsIGRlcGVuZGluZyBvbiB0aGUgaW50ZXJuZXQgY29ubmVjdGlvbiBhbmQgd2hpY2ggc291cmNlIHRoZSBmaWxlcyBhcmUgcHVsbGVkIGZyb20gKG9uLXByZW0sIEFXUyBvciBHQ1ApLgoKCiMjIyMgIlNwb3RzIiBpbiBTUkEgYXJlIG5vdCB0aGUgc2FtZSBhcyAicmVhZHMiCgoqIEEgc3BvdCBpcyBhbGwgdGhlIGluZm8geW91IGdvdCBmcm9tIG9uZSAic3BvdCIgb24gdGhlIGZsb3cgY2VsbC4KKiBZb3UgZ2V0IDQgcmVhZHMgcGVyIHNwb3Qgd2l0aCB0b2RheSdzIGlsbHVtaW5hIHNlcXVlbmNpbmc6IGZvcndhcmQgYmFyY29kZSwgZm9yd2FyZCByZWFkLCByZXZlcnNlIGJhcmNvZGUsIHJldmVyc2UgcmVhZC4gCgohW05DQkkgU1JBICJTcG90cyIgXGxhYmVse1Nwb3RzIGZyb20gU1JBIH1dKC4vaW1hZ2VzL3NwbGl0LTMucG5nKXt3aWR0aD03MCV9CgoKIyMjIyBQcmFjdGljZSBkb3dubG9hZGluZyBkYXRhIGZyb20gU1JBCgpXZSBoYXZlIGEgdG9vbGtpdCBvbiB0aGUgSFBDIGNsdXN0ZXIgdGhhdCBhbGxvd3MgdXNlcnMgdG8gcHVsbCBkYXRhIGRpcmVjdGx5IGZyb20gU1JBLgpUaGUgZmlyc3Qgc3RlcCBpcyBjb25maWd1cmluZyB0aGUgU1JBIHRvb2xraXQgd2l0aCBhIHVuaXF1ZSB1c2VyIElELiBUaGUgc2Vjb25kIHN0ZXAgaXMgcnVubmluZyBlaXRoZXIgYGZhc3RxLWR1bXBgIG9yIGBmYXN0ZXJxLWR1bXBgLiBXZSB3aWxsIHVzZSBgZmFzdHEtZHVtcGAgdG8gZGVtb25zdHJhdGUgdGhlIG9wdGlvbnMgYXZhaWxhYmxlLgoKCmBgYHtiYXNoIHNldCB1cCBTUkEgY29uZmlnfQoKbW9kdWxlIGxvYWQgL2NsdXN0ZXIvdHVmdHMvYmlvL3Rvb2xzL21vZHVsZV9maWxlcy9zcmEvMy4wLjAKCiNUaGUgbmV4dCBmZXcgbGluZXMgc2V0IHVwIHlvdXIgY29uZmlndXJhdGlvbiBmb3IgU1JBIGFuZCBpcyBuZWNlc3NhcnkgaWYgeW91IGhhdmUgbm90IHVzZWQgdGhlIFNSQSB0b29sa2l0IHByZXZpb3VzbHkuCgojVGhlIHZkYi1jb25maWcgaXMgYW4gaW50ZXJhY3RpdmUgdG9vbCwgdG8gZ2VuZXJhdGUgYSB1bmlxdWUgaWRlbnRpZmllci4gU2luY2UgaXQgaXMgZGlmZmljdWx0IHRvIHVzZSBpdCBpbnRlcmFjdGl2ZWx5IGZyb20gUk9uRGVtYW5kLCB0aGlzIGNvbW1hbmQgb3BlbnMgdGhlIGludGVyYWN0aXZlIHNjcmVlbiBmb3IgdGhyZWUgc2Vjb25kcyB0aGVuIGNsb3NlcyBpdCwgd2hpY2ggZ2VuZXJhdGVzIHRoZSB1c2VyIGlkLgoKdmRiLWNvbmZpZyAtaSAmIHJlYWQgLXQgMyA7IGtpbGwgJCEKCmBgYAoKYGBge2Jhc2ggZG93bmxvYWQgYSB0ZXN0IHNldCBmcm9tIFNSQX0KCm1vZHVsZSBsb2FkIC9jbHVzdGVyL3R1ZnRzL2Jpby90b29scy9tb2R1bGVfZmlsZXMvc3JhLzMuMC4wCgpta2RpciAtcCB0ZXN0X1NSQQpmYXN0cS1kdW1wIC0tb3V0ZGlyIHRlc3RfU1JBIC1YIDUwMCAtLXNraXAtdGVjaG5pY2FsIC0tcmVhZC1maWx0ZXIgcGFzcyAtLXJlYWRpZHMgLS1taW5SZWFkTGVuIDIwMCAtLXNwbGl0LWUgU1JSMTgwODYzNjQKCgpgYGAKCgoqKkNvbW1hbmQgTGluZSBQYXJhbWV0ZXJzKioKCiogR3JhcCBmaXJzdCBtaWxsaW9uIGxpbmVzIGAtWCA1MDBgCiogT25seSAiYmlvbG9naWNhbCByZWFkcyIgYC0tc2tpcC10ZWNobmljYWxgCiogUmVtb3ZlIHJlYWRzIHRoYXQgYXJlIG1vc3RseSBOJ3MgIGAtLXJlYWQtZmlsdGVyIHBhc3NgCiogQXBwZW5kIGAuMWAgdG8gZm9yd2FyZCByZWFkIGhlYWRlciBgLjJgIHRvIHJldmVyc2UgcmVhZCBoZWFkZXIgIC0tcmVhZGlkcwoqIEtlZXAgbWF0ZWQgcGFpcnMgYW5kIHNpbmdsZXRvbnMsIHVzZSAt4oCTc3BsaXQtZSBhbmQgYSB0aHJlZSBmaWxlcyB3aWxsIGJlIGdlbmVyYXRlZCBpZiBvcnBoYW5zIGFyZSBwcmVzZW50IChmb3J3YXJkLCByZXZlcnNlLCBhbmQgdW5tYXRjaGVkIG1hdGVzKQoKClRoZXJlIHNob3VsZCBiZSB0aHJlZSBuZXcgZmlsZXMgaW4geW91ciBgTWV0YWdlbm9taWNzMjAyMi90ZXN0X1NSQWAgZGlyZWN0b3J5LgoKVGhlIG91dHB1dCBpcyBzbWFsbCBlbm91Z2ggdGhhdCB3ZSBjYW4gbG9vayBpbnRvIHRoZSBmYXN0cSBmaWxlIGJ5IGNsaWNraW5nIG9uIGl0LgoKKiBDb25maXJtIHRoZSBgLjFgIGFuZCBgLjJgIHdlcmUgYXBwZW5kZWQgdG8geW91ciBmb3J3YXJkIHJlYWQgaGVhZGVycyBhbmQgcmV2ZXJzZSByZWFkIGhlYWRlcnMKKiBXaGF0IGhhcHBlbmVkIGluc2lkZSB0aGUgc2luZ2xldG9uIGZpbGU/IERvIHlvdSBzZWUgYC4xYCwgYC4yYCBvciBib3RoPwoqIFFDIEJlc3QgcHJhY3RpY2U6IENvdW50IHRoZSBudW1iZXIgb2YgbGluZXMgaW4gdGhlIG91dHB1dCBmaWxlcwoKYGBge2Jhc2h9Cgp3YyAtbCAuL3Rlc3RfU1JBLyouZmFzdHEKCmBgYAoqIEhvdyBtYW55IGxpbmVzIGFyZSBpbiBvdXIgZmFzdHEgb3V0cHV0IGZpbGVzIGFuZCB3aHk/IAoKICAoSGludCAxOiB3ZSBhc2tlZCBmb3IgNTAwICJzcG90cyIsIG5vdCByZWFkcykKICAoSGludCAyOiBob3cgZGlkIG91ciBwYXJhbWV0ZXIgY2hvaWNlcyBhZmZlY3Qgb3VyIG91dHB1dHM/KQoKCiMjIyMjIEEgTm90ZSBhYm91dCBGYXN0ZXJxLWR1bXAKCkluIHNvbWUgY2FzZXMsIHRoZSBuZXdlciB2ZXJzaW9uIG9mIHRoaXMgdG9vbCBgZmFzdGVycS1kdW1wYCB3aWxsIGF1dG9tYXRpY2FsbHkgcnVuIHRoZSBzcGxpdC1lIHZlcnNpb24gb2YgdGhlIGNvbW1hbmQgd2l0aG91dCBhZGRpbmcgdGhpcyBwYXJhbWV0ZXIuIEl0IGlzIHdvcnRoIGxvb2tpbmcgYXQgdGhlIG9wdGlvbnMgYmVmb3JlIHVzaW5nIGl0LCBiZWNhdXNlIHNvbWUgb2YgdGhlIHBhcmFtZXRlciBtZWFuaW5ncyBoYXZlIGNoYW5nZWQuCgoKVGhlIGZvbGxvd2luZyBjb2RlYmxvY2sgaXMgZm9yIHJlZmVyZW5jZSwgdG8gdXNlIHRoZSBjaHVuaywgcmVtb3ZlIHRoZSBgI2AgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgbGluZS4KCgpgYGB7YmFzaCwgaW5jbHVkZSA9IEZBTFNFfQoKI3NvdXJjZSB+Ly5iYXNocmMKI21vZHVsZSBsb2FkIC9jbHVzdGVyL3R1ZnRzL2Jpby90b29scy9tb2R1bGVfZmlsZXMvc3JhLzMuMC4wCgojZmFzdHEtZHVtcCAtWCAxMDAwMDAwIC0tc2tpcC10ZWNobmljYWwgLS1jbGlwIC0tcmVhZC1maWx0ZXIgcGFzcyAtLXNwbGl0LXNwb3QgLS1yZWFkaWRzIC0tbWluUmVhZExlbiAyMDAgLS1zcGxpdC1lIFNSUjE4MDg1NjkxCgojZmFzdHEtZHVtcCAtWCAxMDAwMDAwIC0tc2tpcC10ZWNobmljYWwgLS1jbGlwIC0tcmVhZC1maWx0ZXIgcGFzcyAtLXNwbGl0LXNwb3QgLS1yZWFkaWRzIC0tbWluUmVhZExlbiAyMDAgLS1zcGxpdC1lIFNSUjE4MDg1NzA4CgojZmFzdHEtZHVtcCAtWCAxMDAwMDAwIC0tc2tpcC10ZWNobmljYWwgLS1jbGlwIC0tcmVhZC1maWx0ZXIgcGFzcyAtLXNwbGl0LXNwb3QgLS1yZWFkaWRzIC0tbWluUmVhZExlbiAyMDAgLS1zcGxpdC1lIFNSUjE4MDg2Mjc3CgojZmFzdHEtZHVtcCAtWCAxMDAwMDAwIC0tc2tpcC10ZWNobmljYWwgLS1jbGlwIC0tcmVhZC1maWx0ZXIgcGFzcyAtLXNwbGl0LXNwb3QgLS1yZWFkaWRzIC0tbWluUmVhZExlbiAyMDAgLS1zcGxpdC1lIFNSUjE4MDg2MzQyCgojZmFzdHEtZHVtcCAtWCAxMDAwMDAwIC0tc2tpcC10ZWNobmljYWwgLS1jbGlwIC0tcmVhZC1maWx0ZXIgcGFzcyAtLXNwbGl0LXNwb3QgLS1yZWFkaWRzIC0tbWluUmVhZExlbiAyMDAgLS1zcGxpdC1lIFNSUjE4MDg2MzY0CgojZmFzdHEtZHVtcCAtWCAxMDAwMDAwIC0tc2tpcC10ZWNobmljYWwgLS1jbGlwIC0tcmVhZC1maWx0ZXIgcGFzcyAtLXNwbGl0LXNwb3QgLS1yZWFkaWRzIC0tbWluUmVhZExlbiAyMDAgLS1zcGxpdC1lIFNSUjE4MDg2NTc1CgojZmFzdHEtZHVtcCAtWCAxMDAwMDAwIC0tc2tpcC10ZWNobmljYWwgLS1jbGlwIC0tcmVhZC1maWx0ZXIgcGFzcyAtLXNwbGl0LXNwb3QgLS1yZWFkaWRzIC0tbWluUmVhZExlbiAyMDAgLS1zcGxpdC1lIFNSUjE4MDkxMzE2CgojZmFzdHEtZHVtcCAtWCAxMDAwMDAwIC0tc2tpcC10ZWNobmljYWwgLS1jbGlwIC0tcmVhZC1maWx0ZXIgcGFzcyAtLXNwbGl0LXNwb3QgLS1yZWFkaWRzIC0tbWluUmVhZExlbiAyMDAgLS1zcGxpdC1lIFNSUjE4MDkxNzM3CgpgYGAKCgoKCiMjIyMgIAoKYGBge2Jhc2ggcXVhbGl0eSBjaGVjayBvZiB0aGUgcmF3IGZpbGVzfQoKIy9jbHVzdGVyL3R1ZnRzL2hwYy90b29scy9zcGFjay9saW51eC1yaGVsNy1pdnlicmlkZ2UvZ2NjLTkuMy4wL2Zhc3RxYy0wLjExLjktZWVpajVqd253YXUzdHR4NG01M2J4YWZteGJobTRmanovYmluL2Zhc3RxYyAuL01HRGF0YS8qb3ZlcnJlcC5mYXN0cQoKI3NvdXJjZSB+Ly5iYXNocmMKbW9kdWxlIGxvYWQgZmFzdHFjCm1rZGlyIC1wIGZhc3RxYwpmYXN0cWMgLi9kYXRhLypwYXNzKi5mYXN0cSAtbyBmYXN0cWMKCmBgYAoKYGBge2Jhc2ggYWdncmVnYXRlIHRoZSByYXcgcXVhbGl0eSBjaGVja30KCiNzb3VyY2Ugfi8uYmFzaHJjCm1vZHVsZSBsb2FkIG11bHRpcWMvMS43LjAKbWtkaXIgLXAgbXVsdGlxYwptdWx0aXFjIC4vZmFzdHFjIC1vIC4vbXVsdGlxYwoKYGBgCgpDaGVjayB0aGUgcXVhbGl0eSBvZiB5b3VyIHJlc3VsdHMgYnkgbmF2aWdhdGluZyB0byB0aGUgZmlsZSBmb2xkZXIgZm9yIG11bHRpcWMgYW5kIGNsaWNraW5nIG9uIHRoZSBodG1sIGZpbGVzIHRoYXQgd2VyZSBnZW5lcmF0ZWQuCgpPa2F5LCBzbyB0aGUgZGF0YSBpcyBub3QgdGhlIG1vc3QgcGVyZmVjdCwgYnV0IHdlIGp1c3QgbmVlZCBhIHNldCB0aGF0IGNhbiBtYWtlIGl0IHRocm91Z2ggdGhlIGFuYWx5c2lzLgoKIyMgUHJlcHJvY2Vzc2luZyBSZWFkcwoKTWV0YWdlbm9taWNzIGhhcyBiZW5lZml0ZWQgZnJvbSBrLW1lciBiYXNlZCBhcHByb2FjaGVzLgoKQkNCaW8gdG9vbHMgYXJlIHVzZWZ1bCBmb3IgY2xlYWluaW5nIG1ldGFnZW5vbWljcyBmaWxlcywgYmVjYXVzZSBtYW55IHNpbXBsZSBmdW5jdGlvbnMgY2FuIGJlIGNhbGxlZCBhbmQgc3BlZCB1cCB1c2luZyBrbWVycy4KCkZvciBleGFtcGxlLCBsZXQncyByZW1vdmUga25vd24gYWRhcHRlciBhbmQgb3RoZXIgY29udGFtaW5hdGlvbiB1c2luZyB0aGUgTkNCSSBkYXRhYmFzZSBjYWxsZWQgIlVuaVZlYyIKCgoKCmBgYHtiYXNoIGxvb2sgYXQgVW5pVmVjLmZhc3RhfQoKY2Qgfi9NZXRhZ2Vub21pY3MyMDIyCiNwd2QKCiNncmVwICJUcnVTZXEiIC4vY29udGFtaW5hbnRzL1VuaVZlYy5mYXN0YQoKZ3JlcCAiUENSIFByaW1lciBJbmRleCA5IiAuL2NvbnRhbWluYW50cy9VbmlWZWMuZmFzdGEKCgoKYGBgCgoKIyMjIFJlbW92ZSBjb250YW1pbmF0aW9uIGZyb20gc2VxdWVuY2VzIHdpdGggQkNCaW8gdG9vbHMKCkFyZSB0aGVzZSByZXBlYXRzIGJpb2xvZ2ljYWwgKHBhcnQgb2YgdGhlIGdlbm9tZSkgb3IgdGVjaG5pY2FsIChwcmltZXIgYW1wbGlmaWNhdGlvbiwgdW5kZXJhYnVuZGFuY2Ugb2Ygc2FtcGxlIG9yIGxhY2sgb2YgUGhpWCBzcGlrZS1pbik/IFdoYXQgZG9lcyB0aGUgcmF3IHNlcXVlbmNpbmcgZGF0YSBzaG93IHVzPwoKCkhlcmUgaXMgYW4gZXhhbXBsZSBvZiBob3cgYmJkdWsuc2ggY2FuIGJlIHVzZWQgdG8gc2ltdWx0YW5lb3VzbHkgcmVtb3ZlIGFkYXB0ZXJzLCBwaGlYIHNwaWtlLWluIGFuZCBvdmVycmVwcmVzZW50ZWQgc2VxdWVuY2VzIGZyb20gb3VyIGN1c3RvbSBmaWxlLgoKYGBge2Jhc2ggcmVtb3ZlIHNlcXVlbmNlcyBvbiByYXcgZGF0YSBmaWxlfQoKI3NvdXJjZSB+Ly5iYXNocmMKbW9kdWxlIGxvYWQgamF2YS8xLjguMF82MAptb2R1bGUgbG9hZCAvY2x1c3Rlci90dWZ0cy9iaW8vdG9vbHMvbW9kdWxlX2ZpbGVzL2JjYmlvLzEuMS41Cm1rZGlyIC1wIGRlY29uCgoKYmJkdWsuc2ggLVhteDEwZyAtdGJvICAtdHBlIFwKaW4xPWRhdGEvU1JSMTgwODU2OTFfcGFzc18xLmZhc3RxIFwKaW4yPWRhdGEvU1JSMTgwODU2OTFfcGFzc18yLmZhc3RxIFwKb3V0MT1kZWNvbi9TUlIxODA4NTY5MV9kZWNvbl8xLmZhc3RxIFwKb3V0Mj1kZWNvbi9TUlIxODA4NTY5MV9kZWNvbl8yLmZhc3RxIFwKb3V0cz1kZWNvbi9TUlIxODA4NTY5MV9kZWNvbl9zaW5nLmZhc3RxIFwKcmVmPWNvbnRhbWluYW50cy9VbmlWZWMuZmFzdGEgXApyZWY9Y29udGFtaW5hbnRzL292ZXJyZXAuZmFzdGEgXApyZWY9YWRhcHRlcnMgXApyZWY9cGhpeCBcCmt0cmltPXIgaz0yMSByY29tcD10IG1pbms9MTEgaGRpc3Q9MiBtaW5sZW49MjAwIFwKCgpgYGAKCiMjIyMgV2hpbGUgdGhlIG5leHQgY2h1bmsgaXMgcnVubmluZywgbGV0J3MgdGFsayBhYm91dCBrbWVyLWJhc2VkIGFwcHJvYWNoZXMgdG8gZmlsdGVyaW5nLgoKW0JCRFVLID0gRGVjb250YW1pbmF0aW9uIFVzaW5nIEttZXJzXShodHRwczovL2pnaS5kb2UuZ292L2RhdGEtYW5kLXRvb2xzL3NvZnR3YXJlLXRvb2xzL2JidG9vbHMvYmItdG9vbHMtdXNlci1ndWlkZS9iYmR1ay1ndWlkZS8pCgoqIGAtdGJvYCB0cmltcyBvdmVybGFwcGluZyBiYXNlcyBpbiBwYWlyZWQgZW5kIHJlYWRzCiogYC10cGVgIHRyaW1zIGJvdGggcGFpcmVkIGVuZCByZWFkcyB0byB0aGUgc2FtZSBsZW5ndGgKKiBgLWluMWAsYC1pbjJgLGBvdXQxYCxgb3V0MmAsYG91dHNgIG1lYW5zIGlucHV0IGZvcndhcmQgYW5kIHJldmVyc2UgcmVhZHMgYW5kIG91dHB1dCBmb3J3YXJkIGFuZCByZXZlcnNlIHBsdXMgb3JwaGFuZWQgcmVhZHMKKiBgcmVmYCBjYW4gYmUgYW55IGZpbGUgaW4gZmFzdGEgZm9ybWF0IG9yIGJha2VkLWluIG9wdGlvbnMgc3VjaCBhcyBgcGhpWGAgYW5kIGBhZGFwdGVyc2AKKiBgcmVmYCBjYW4gYmUgcmVwbGFjZWQgd2l0aCBgbGl0ZXJhbD1BQ1RHR1QsVFRUR0dUR2Agd2l0aCBhbnkgbGlzdCBvZiBzdHJpbmdzCiogYGt0cmltPXJgIG1lYW5zIHRvIHRyaW0gZnJvbSBgMy1wcmltZWAgZW5kCiogYGtgIHJlZmVycyB0byB0aGUgYGttZXJgIHNpemUgdGhhdCBpcyBjaG9zZW4KKiBgbWlua2AgYWxsb3dzIGEgc2hvcnRlciBga21lcmAgc2l6ZSBhdCB0aGUgZW5kIG9mIHRoZSBzZXF1ZW5jZQoqIGBoZGlzdGAgcmVmZXJzIHRvIGhhbW1pbmcgZGlzdGFuY2UgLSBudW1iZXIgb2YgbWlzbWF0Y2hlcyBhbGxvd2VkIGluIGEga21lcgoqIGBtaW5sZW5gIGluZGljYXRlcyB0aGUgbWluaW11bSBsZW5ndGggb2YgdGhlIHNlcXVlbmNlIHRvIGtlZXAgYWZ0ZXIgdHJpbW1pbmcKCgoKYGBge2Jhc2ggcmVtb3ZlIHNlcXVlbmNlcyBvbiBhbGwgcmF3IGRhdGEgZmlsZXN9Cgojc291cmNlIH4vLmJhc2hyYwptb2R1bGUgbG9hZCBqYXZhLzEuOC4wXzYwCm1vZHVsZSBsb2FkIC9jbHVzdGVyL3R1ZnRzL2Jpby90b29scy9tb2R1bGVfZmlsZXMvYmNiaW8vMS4xLjUKbWtkaXIgLXAgZGVjb24KCgpscyBkYXRhLypfcGFzc18xLmZhc3RxIHwgd2hpbGUgcmVhZCBsaW5lIDsgZG8gXAoKYmJkdWsuc2ggLVhteDEwZyAtdGJvIC10cGUgXAppbjE9JGxpbmUgXAppbjI9ZGF0YS8kKGJhc2VuYW1lICRsaW5lIF9wYXNzXzEuZmFzdHEpX3Bhc3NfMi5mYXN0cSBcCm91dDE9ZGVjb24vJChiYXNlbmFtZSAkbGluZSBfcGFzc18xLmZhc3RxKV9kZWNvbl8xLmZhc3RxIFwKb3V0Mj1kZWNvbi8kKGJhc2VuYW1lICRsaW5lIF9wYXNzXzEuZmFzdHEpX2RlY29uXzIuZmFzdHFcIFwKb3V0cz1kZWNvbi8kKGJhc2VuYW1lICRsaW5lIF9wYXNzXzEuZmFzdHEpX2RlY29uX3NpbmcuZmFzdHEgXApyZWY9Y29udGFtaW5hbnRzL1VuaVZlYy5mYXN0YSBcCnJlZj1jb250YW1pbmFudHMvb3ZlcnJlcC5mYXN0YSBcCnJlZj1waGl4IFwKa3RyaW09ciBrPTIxIHJjb21wPXQgbWluaz0xMSBoZGlzdD0yIG1pbmxlbj0yMDA7IFwKZG9uZQoKCgoKYGBgCgoKCgoKCgpgYGB7YmFzaCBxdWFsaXR5IGNoZWNrIGRlY29uIGZpbGVzfQojc291cmNlIH4vLmJhc2hyYwptb2R1bGUgbG9hZCBmYXN0cWMKbWtkaXIgLXAgZmFzdHFjX2RlY29uCmZhc3RxYyAuL2RlY29uLypkZWNvbiouZmFzdHEgLW8gZmFzdHFjX2RlY29uCgpgYGAKCgoKCgoKYGBge2Jhc2ggYWdncmVnYXRlIHRoZSBkZWNvbiBxdWFsaXR5IGNoZWNrfQoKI3NvdXJjZSB+Ly5iYXNocmMKbW9kdWxlIGxvYWQgbXVsdGlxYy8xLjcuMApta2RpciAtcCBtdWx0aXFjX2RlY29uCm11bHRpcWMgLi9mYXN0cWNfZGVjb24gLW8gLi9tdWx0aXFjX2RlY29uCgpgYGAKCgoKIyMjIyBRdWVzdGlvbjogRGlkIHdlIGdldCByaWQgb2YgYWxsIHRoZSBhZGFwdGVyIHNlcXVlbmNlcz8gV2hhdCB3b3VsZCB5b3VyIG5leHQgc3RlcCBiZT8KCgojIyMjIFF1ZXN0aW9uOiBJcyB0aGVyZSBhIHBhcnRpY3VsYXIgdGljayBwb29sIHRoYXQgd2UgbWF5IHdhbnQgdG8gcmVtb3ZlIGJlZm9yZSBhc3NlbWJseT8KClRvIGJlIHJlbW92ZWQgYmVmb3JlIGFzc2VtYmx5OgoKKiBJZ25vcmUgc2luZ2xlIHJlYWRzCiogSWdub3JlIGxvdyBjb3VudCByZWFkcyAoU1JSMTgwODYzNjQpCiogSWdub3JlIGxvdyBxdWFsaXR5IHJlYWRzIChTUlIxODA5MTczNyxTUlIxODA4NjI3NykKCgpgYGB7YmFzaCBrZWVwIHRoZSBnb29kIHRpY2tzfQoKbWtkaXIgLXAgZ29vZGRhdGEKCmVjaG8gU1JSMTgwODU2OTEgPiBnb29kZGF0YS50eHQKZWNobyBTUlIxODA4NTcwOCA+PiBnb29kZGF0YS50eHQKZWNobyBTUlIxODA4NjM0MiA+PiBnb29kZGF0YS50eHQKZWNobyBTUlIxODA4NjU3NSA+PiBnb29kZGF0YS50eHQKZWNobyBTUlIxODA5MTMxNiA+PiBnb29kZGF0YS50eHQKCgpjYXQgZ29vZGRhdGEudHh0IHwgd2hpbGUgcmVhZCAkbGluZTsgZG8gY3AgZGVjb24vJGxpbmUqMS5mYXN0cSBnb29kZGF0YTsgY3AgZGVjb24vJGxpbmUqMi5mYXN0cSBnb29kZGF0YTsgZG9uZQoKYGBgCgpUaGlzIGNvbmNsdWRlcyBQYXJ0IEksIHBsZWFzZSBjb21lIGJhY2sgYWZ0ZXIgdGhlIGJyZWFrIGZvciBQYXJ0IElJIC0gdXNpbmcgYSB3cmFwcGVyIHNjcmlwdCB0byBiaW4geW91ciBkYXRhLgoKCi0tLQoKIyMgUGFydCBJSQoKCiMjIyBSdW5uaW5nIGFuIEFzc2VtYmx5IG9uIHRoZSBDbGVhbmVkIERhdGEKCiMjIyMgVGhpcyBjb21tYW5kIHRha2VzIGFwcHJveGltYXRlbHkgMjAgbWludXRlcywgc28gdGhlIGNvbW1hbmRzIHVzZWQgdG8gbWFrZSB0aGUgYXNzZW1ibHkgYXJlIGNvbW1lbnRlZCBvdXQuCgoKYGBge2Jhc2ggcnVuIG1ldGFnZW5vbWUgYXNzZW1ibHl9CgoKIy9jbHVzdGVyL3R1ZnRzL2Jpby90b29scy9tZWdhaGl0LzEuMi45L2Jpbi9tZWdhaGl0ICAtbSAxNjAwMDAwMCAtdCAzMiAtLXJlYWQgLi9nb29kZGF0YS8qIFwKIy0tay1saXN0IDIxLDQxLDYxLDgxLDk5IFwKIy0tbm8tbWVyY3kgXAojLS1taW4tY291bnQgMiBcCiMtbyBtZWdhaGl0X291dC8KCmBgYAoKW01lZ2FoaXQ6IGRlIEJydWlqbiBncmFwaCBBc3NlbWJseV0oaHR0cHM6Ly9hY2FkZW1pYy5vdXAuY29tL2Jpb2luZm9ybWF0aWNzL2FydGljbGUvMzEvMTAvMTY3NC8xNzc4ODQpCgoKIVtNZWdhaGl0IHdvcmtmbG93IFxsYWJlbHtNZWdhaGl0IHdvcmtmbG93fV0oLi9pbWFnZXMvbWVnYWhpdF93b3JrZmxvdy5wbmcpe3dpZHRoPTMwJX0KCiMjIyMgV2hhdCBpcyBhIGRlQnJ1aWpuIGdyYXBoPwoKSXQgaXMgYW4gYXNzZW1ibHkgYWxnb3JpdGhtIHRoYXQgc3BsaXRzIHlvdXIgc2VxdWVuY2UgaW50byBrLW1lcnMgYW5kIHRyaWVzIHRvIGJ1aWxkIHRoZSBsb25nZXN0IGNvbnRpZ3MgYWxvbmcgdGhlIHNob3J0ZXN0IHBhcnNpbW9uaW91cyBwYXRoLgoKIVtNZWdhaGl0IHdvcmtmbG93IFxsYWJlbHtTb2huLCBqYW5nLWlsICYgTmFtLCBKaW4tV3UuICgyMDE2KS4gVGhlIHByZXNlbnQgYW5kIGZ1dHVyZSBvZiBkZSBub3ZvIHdob2xlLWdlbm9tZSBhc3NlbWJseS4gQnJpZWZpbmdzIGluIEJpb2luZm9ybWF0aWNzLiAxOS4gYmJ3MDk2LiAxMC4xMDkzL2JpYi9iYncwOTZ9XSguL2ltYWdlcy9kZUJydWlqbi5wbmcpCiAKCgoKVG8gc2F2ZSB0aW1lIGluIHRoZSB3b3Jrc2hvcCwgdGhlIGFzc2VtYmx5IGhhcyBiZWVuIGRvbmUgdXNpbmcgdGhlIGNvbW1lbnRlZCBvdXQgY29tbWFuZCBhYm92ZSBhbmQgcGxhY2VkIGludG8geW91ciB3b3Jrc2hvcCBmb2xkZXIgY2FsbGVkICJyZXBvcnRzIi4KCgojIyMgQ2hlY2tpbmcgdGhlIHF1YWxpdHkgb2Ygb3VyIEFzc2VtYmx5CgpbUXVhc3RdKGh0dHBzOi8vYWNhZGVtaWMub3VwLmNvbS9iaW9pbmZvcm1hdGljcy9hcnRpY2xlLzI5LzgvMTA3Mi8yMjg4MzIpIGlzIGEgY29tbW9ubHkgdXNlZCB0b29sIHRvIGFzc2VzcyBhc3NlbWJsaWVzLiBJdCB3aWxsIHByb3ZpZGUgYSByZXBvcnQgdGhhdCBpcyBlaXRoZXIgaW4gYSB0ZXh0IGZpbGUgb3IgYW4gaHRtbC4KCkxldCdzIHJ1biB0aGUgZm9sbG93aW5nIGNvbW1hbmQgYW5kIHRoZW4gbG9vayBmb3IgdGhlIHF1YXN0IHJlcG9ydCB0byBzZWUgaWYgd2UgaGF2ZSBhICJnb29kIiBhc3NlbWJseS4KCgpgYGB7YmFzaCBxdWFzdCBhbmFseXNpc30KCi9jbHVzdGVyL3R1ZnRzL2Jpby90b29scy9xdWFzdC81LjIuMC9xdWFzdC5weSAtbyBxdWFzdF9hc3NlbWJseSAuL3JlcG9ydHMvZmluYWwuY29udGlncy5mYQoKYGBgCgojIyMgVXNpbmcgS3Jha2VuIHRvIGNoZWNrIGZvciBNZXRhZ2Vub21lIENvbXBvc2l0aW9uCgpBdCB0aGlzIHBvaW50LCB3ZSBtYXkgYmUgaW50ZXJlc3RlZCBpbiB3aGV0aGVyIG91ciBhc3NlbWJseSBtYWtlcyBzZW5zZSBmb3Igb3VyIHNldCBvZiBjb250aWdzLgoKW0tyYWtlbjJdKGh0dHBzOi8vY2NiLmpodS5lZHUvc29mdHdhcmUva3Jha2VuMi8pIGlzIHRoZSBuZXdlc3QgdmVyc2lvbiBvZiBLcmFrZW4sIGEgdGF4b25vbWljIGNsYXNzaWZpY2F0aW9uIHN5c3RlbSB1c2luZyBleGFjdCBrLW1lciBtYXRjaGVzLiBUaGlzIGstbWVyIGJhc2VkIGFwcHJvYWNoIGhhcyB2ZXJ5IGZhc3QgY2xhc3NpZmljYXRpb24gc3BlZWRzIHdpdGggaGlnaCBhY2N1cmFjeS4KClRoaXMgYXBwcm9hY2ggZGlmZmVycyBmcm9tIGhvbW9sb2d5IGJhc2VkIGFwcHJvYWNoZXMgdGhhdCB0cnkgdG8gbWF0Y2ggc2VxdWVuY2VzIHRvIGVhY2ggb3RoZXIgYW5kIHNjb3JlIHRoZW0gYmFzZWQgb24gdGhlIG51bWJlciBvZiBtaXNtYXRjaGVzLCBkZWxldGlvbnMgYW5kIGluc2VydHMuIEtyYWtlbiB1c2VzIHRoZSBlbnRpcmUga21lciBjb21wb3NpdGlvbiBvZiB0aGUgY29udGlnIHRvIG1hdGNoIGl0IHRvIGEgZGF0YWJhc2Ugd2hlcmUgcmVmZXJlbmNlIHNlcXVlbmNlcyBoYXZlIGJlZW4gYnJva2VuIGRvd24gaW50byBrbWVyICJoYXNoZXMiIG9yIGEgZGF0YWJhc2Ugb2Ygd2hhdCB0aGUga21lcnMgbG9vayBsaWtlIGZvciBhIHBhcnRpY3VsYXIgb3JnYW5pc20uCgoKYGBge2Jhc2gga3Jha2VuIGNsYXNzaWZpY2F0aW9uIG9mIG91ciBhc3NlbWJseX0KCi9jbHVzdGVyL3R1ZnRzL2Jpby90b29scy9jb25kYV9lbnZzL2tyYWtlbi8yLjEuMi9iaW4va3Jha2VuMiAtLXVzZS1uYW1lcyAtLXRocmVhZHMgNCAtLWRiIC9jbHVzdGVyL3R1ZnRzL2Jpby90b29scy90cmFpbmluZy9tZXRhZ2Vub21pY3Mva3Jha2VuX3ZpcnVzIC0tcmVwb3J0IGtyYWtlbi5yZXBvcnQudHh0IC0tcXVpY2sgcmVwb3J0cy9maW5hbC5jb250aWdzLmZhIC0tY2xhc3NpZmllZC1vdXQgY2xhc3NpZmllZF9zZXF1ZW5jZXMudHN2ID4gc2VxdWVuY2VzLmtyYWtlbgoKCmBgYApgYGB7YmFzaH0KCmhlYWQgY2xhc3NpZmllZF9zZXF1ZW5jZXMudHN2CmBgYAoKV2UgY2FuIG9wZW4gdXAgdGhlIHNlcXVlbmNlIHJlcG9ydCBpbnNpZGUgUlN0dWRpbyBPbkRlbWFuZCBhbmQgc2Nyb2xsIHRocm91Z2ggdGhlIGZpbmRpbmdzLgoKVGhpcyBjYW4gYmUgYSB2ZXJ5IGxvbmcgbGlzdCBvZiBzcGVjaWVzIG5hbWVzLCBzbyBpdCBtYXkgYmUgbW9yZSBoZWxwZnVsIHRvIHVzZSBhbiBpbnRlcmFjdGl2ZSB2aXN1YWxpemF0aW9uIHRvb2wgdG8gbG9vayBhdCBvdXIgZGF0YS4KCgpbS3JvbmFdKGh0dHBzOi8vYm1jYmlvaW5mb3JtYXRpY3MuYmlvbWVkY2VudHJhbC5jb20vYXJ0aWNsZXMvMTAuMTE4Ni8xNDcxLTIxMDUtMTItMzg1KSBpcyBhIHZlcnkgdXNlZnVsIHRvb2wgdGhhdCBjYW4gdGFrZSBpbiBhIHZhcmlldHkgb2YgZm9ybWF0cy4gSW4gdGhpcyBjYXNlLCB3ZSBhcmUgcHJvdmlkaW5nIG91ciBrcmFrZW4ucmVwb3J0IHRvIHRoZSB2aXN1YWxpemF0aW9uLiBNZXRhYmFyY29kaW5nIGRhdGEgYXNzaWduZWQgdG8gYSB0YXhvbm9teSBjYW4gYWxzbyBiZSB1c2VkIGluIHRoaXMgY2FzZS4KCgpgYGB7YmFzaH0KCi9jbHVzdGVyL3R1ZnRzL2Jpby90b29scy9jb25kYV9lbnZzL2tyYWtlbi8yLjEuMi9iaW4va3RJbXBvcnRUYXhvbm9teSAtdCA1IC1tIDMgLW8ga3JvbmEuaHRtbCBrcmFrZW4ucmVwb3J0LnR4dAoKYGBgCgoKVGhlIG91dHB1dCwgd2hlbiBvcGVuZWQgaW4gYSB3ZWIgYnJvd3NlciwgYWxsb3dzIHRoZSB1c2VyIHRvIGludGVyYWN0IHdpdGggdGhlIGRhdGEgYW5kIGV4cGxvcmUgZGlmZmVyZW50IGxldmVscyBvZiB0aGUgZGF0YS4KCiFbS3JvbmEgb3V0cHV0IFxsYWJlbHtLcm9uYSBvdXRwdXR9XSguL2ltYWdlcy9rcm9uYV9leGFtcGxlLnBuZykKCgoKCiMjIyBXaGF0IGNhbiB3ZSBkbyB3aXRoIE1ldGFnZW5vbWljIEFwcHJvYWNoZXMKCiMjIyBDYXNlIFN0dWR5OiBEZXNjcmliaW5nIGEgQ29tcGxldGUgQ3lhbm9iYWN0ZXJpYWwgR2Vub21lIGFuZCBpdHMgU3ltYmlvbnRzIGZyb20gYW4gRXh0cmVtZWx5IEFyaWQgRW52aXJvbm1lbnQKCiMjIyMgVGhlIEF0YWNhbWEgRGVzZXJ0IC0gQXJlIHdlIG9uIE1hcnM/CgohW0F0YWNhbWEgRGVzZXJ0IFxsYWJlbHtBdGFjYW1hIERlc2VydCBFU08vUy4gTG93ZXJ5IC0gaHR0cHM6Ly93d3cuZXNvLm9yZy9wdWJsaWMvaW1hZ2VzL3BvdHcxNzE4YS99XSguL2ltYWdlcy9BdGFjYW1hLmpwZWcpCgoKClNvIHdlIGFyZSBwcm9iYWJseSBydW5uaW5nIG91dCBvZiB0aW1lIHRvIGNvbnRpbnVlIHdvcmtpbmcgaGFuZHMgb24uCgpMZXQncyB0YWtlIHNvbWUgdGltZSB0byBkaXNjdXNzIHdoYXQgdGhlIG5leHQgc3RlcHMgbWlnaHQgbG9vayBsaWtlLgoKVGhpcyBkaXNjdXNzaW9uIHdpbGwgY2VudGVyIGFyb3VuZCBhIHJlY2VudCBwcm9qZWN0IGZyb20gRHIuIFBlYXJzb24ncyBsYWIsIGNvbmR1Y3RlZCBieSBOZXZlZGEgTmF6LCBQaC5ELgoKTmV2ZWRhIGJ1aWxkcyBsaXR0bGUgcm9ib3RzIGFuZCBzZW5kcyB0aGVtIHRvIG91dGVyc3BhY2UuIChOZXZlZGEgaWYgeW91IGFyZSBoZXJlLCBmZWVsIGZyZWUgdG8gY29tbWVudCEpCgoKW1BsZWFzZSBvcGVuIHVwIHRoaXMgcGRmIGhlcmVdKGh0dHBzOi8vZ2l0aHViLmNvbS90dWZ0c2RhdGFsYWIvdHVmdHNXb3Jrc2hvcHMvYmxvYi9tYWluL2RvY3Mvb21pY3MvaW50cm8tbWV0YWdlbm9taWNzL01ldGFnZW5vbWljX3dvcmtmbG93X2V4YW1wbGUucGRmKSB0byBmaW5kIHRoZSBkaXNjdXNzaW9uLgoKCgojIyMjIEhlbHBmdWwgUmVzb3VyY2VzCgpBbHNvLCBmb3IgZnV0dXJlIHJlYWRpbmcsIEkgaGF2ZSBwbGFjZWQgdHdvIHVzZWZ1bCAucGRmJ3MgaW4gb3VyIHB1YmxpYyBnaXRodWIgcGFnZXMgdGhhdCBzdW1tYXJpemUgdGhlIHN0ZXBzIHdlIGFyZSBkaXNjdXNzaW5nIGluIGZ1cnRoZXIgZGV0YWlsLgoKW0Vzc2VudGlhbHMgaW4gTWV0YWdlbm9taWNzIEldKGh0dHBzOi8vZ2l0aHViLmNvbS90dWZ0c2RhdGFsYWIvdHVmdHNXb3Jrc2hvcHMvYmxvYi9tYWluL2RvY3Mvb21pY3MvaW50cm8tbWV0YWdlbm9taWNzL01ldGFnZW5vbWljc19Fc3NlbnRpYWxzXzEucGRmKQpbRXNzZW50aWFscyBpbiBNZXRhZ2Vub21pY3MgSUldKGh0dHBzOi8vZ2l0aHViLmNvbS90dWZ0c2RhdGFsYWIvdHVmdHNXb3Jrc2hvcHMvYmxvYi9tYWluL2RvY3Mvb21pY3MvaW50cm8tbWV0YWdlbm9taWNzL01ldGFnZW5vbWljc19Fc3NlbnRpYWxzXzIucGRmKQoKVGhpcyBtYXJrZG93biBhbmQgYXNzb2NpYXRlZCBmaWxlcyB3aWxsIGJlIHBsYWNlZCBpbiBvdXIgR2l0aHViIGFuZCBtYWlsZWQgb3V0IHRvIHRoZSBjbGFzcyBzaG9ydGx5LgoKV2Ugd2lsbCBhbHNvIHNlbmQgb3V0IGEgdmlkZW8gb2YgdGhpcyB3b3Jrc2hvcC4KCiMjIyMgUGxlYXNlIFByb3ZpZGUgRmVlZGJhY2sKCkphc29uIGFuZCBJIGhvcGUgdG8gY29udGludWUgZGV2ZWxvcGluZyB0aGlzIHByYWN0aWNhbCBtYXRlcmlhbCB0byBwcm92aWRlIG1vcmUgaGFuZHMtb24gZXhwZXJpZW5jZSBpbiB0aGUgZnV0dXJlLCBzbyBhbnkgZmVlZGJhY2sgb24gdGhlIHRvb2xzIHlvdSB3b3VsZCBsaWtlIHRvIGV4cGxvcmUgaXMgYXBwcmVjaWF0ZWQuCgoKCgoKCg==